From c81276e7c75176d914ed0674975ebebea5d36c2d Mon Sep 17 00:00:00 2001 From: Caleb Briancesco Date: Thu, 19 Dec 2024 11:35:12 -0600 Subject: [PATCH] feat: adding wallet type switch and transactions hook to mock transactions --- .../components/auth/hooks/useTransaction.ts | 84 +++++++++++++++++++ examples/ui-demo/src/app/page.tsx | 2 + .../configuration/Configuration.tsx | 51 +++++++++++ .../ui-demo/src/components/icons/settings.tsx | 21 +++++ .../components/shared/WalletTypeSwitch.tsx | 53 ++++++++++++ 5 files changed, 211 insertions(+) create mode 100644 account-kit/react/src/components/auth/hooks/useTransaction.ts create mode 100644 examples/ui-demo/src/components/configuration/Configuration.tsx create mode 100644 examples/ui-demo/src/components/icons/settings.tsx create mode 100644 examples/ui-demo/src/components/shared/WalletTypeSwitch.tsx diff --git a/account-kit/react/src/components/auth/hooks/useTransaction.ts b/account-kit/react/src/components/auth/hooks/useTransaction.ts new file mode 100644 index 0000000000..f180fcaf7f --- /dev/null +++ b/account-kit/react/src/components/auth/hooks/useTransaction.ts @@ -0,0 +1,84 @@ +import { useState } from "react"; + +export enum TransactionStatus { + none = "none", + pending = "pending", + success = "success", + error = "error", +} + +export interface Transaction { + title: string; + status: TransactionStatus; +} + +export interface TransactionConfig { + stepsNumber?: number; +} + +export interface UseTransaction { + makeRequest: () => void; + result: Transaction[]; + reset: () => void; +} + +const randomDelay = (min = 2, max = 6) => { + const delay = Math.floor(Math.random() * (max - min + 1)) + min; + return delay * 1000; +}; + +export const useTransaction = ( + { stepsNumber = 3 }: TransactionConfig = { stepsNumber: 3 } +): UseTransaction => { + const baseRequest = Array.from({ length: stepsNumber }).map( + (_item, index) => ({ + title: `Transaction ${index + 1}`, + status: TransactionStatus.none, + }) + ); + + const [result, setResult] = useState(baseRequest); + + const reset = () => { + setResult(baseRequest); + }; + + const simulateApiCall = async ( + transaction: Transaction + ): Promise => { + return new Promise((resolve) => { + setTimeout(() => { + resolve({ ...transaction, status: TransactionStatus.success }); + }, randomDelay()); + }); + }; + + const makeRequest = async () => { + for (let i = 0; i < result.length; i++) { + const response = await simulateApiCall(result[i]); + + setResult((prevState) => { + const newState = [...prevState]; + newState[i] = response; + return newState; + }); + } + }; + + const startRequest = () => { + setResult((prevState) => { + return [...prevState].map((item) => ({ + ...item, + status: TransactionStatus.pending, + })); + }); + + makeRequest(); + }; + + return { + makeRequest: startRequest, + result, + reset, + }; +}; diff --git a/examples/ui-demo/src/app/page.tsx b/examples/ui-demo/src/app/page.tsx index 0a8b799485..c7fa485360 100644 --- a/examples/ui-demo/src/app/page.tsx +++ b/examples/ui-demo/src/app/page.tsx @@ -20,6 +20,7 @@ import { AuthCardWrapper } from "../components/preview/AuthCardWrapper"; import { CodePreview } from "../components/preview/CodePreview"; import { CodePreviewSwitch } from "../components/shared/CodePreviewSwitch"; import { TopNav } from "../components/topnav/TopNav"; +import { Configuration } from "@/components/configuration/Configuration"; const publicSans = Public_Sans({ subsets: ["latin"], @@ -47,6 +48,7 @@ export default function Home() { >
+
diff --git a/examples/ui-demo/src/components/configuration/Configuration.tsx b/examples/ui-demo/src/components/configuration/Configuration.tsx new file mode 100644 index 0000000000..d5e8dff5da --- /dev/null +++ b/examples/ui-demo/src/components/configuration/Configuration.tsx @@ -0,0 +1,51 @@ +import { useState } from "react"; +import { cn } from "@/lib/utils"; + +import { SettingsIcon } from "../icons/settings"; +// import { HelpTooltip } from "../shared/HelpTooltip"; +import { WalletTypeSwitch } from "../shared/WalletTypeSwitch"; +import ExternalLink from "../shared/ExternalLink"; + +enum WalletTypes { + smart = "smart", + smart7702 = "7702", +} +export const Configuration = ({ className }: { className?: string }) => { + const [walletType, setWalletType] = useState(WalletTypes.smart); + + const onSwitchWalletType = () => { + setWalletType( + walletType === WalletTypes.smart + ? WalletTypes.smart7702 + : WalletTypes.smart + ); + }; + + return ( +
+
+ + Configuration +
+
+

+ Embedded Wallet Type{" "} +

+ {/* */} +
+ +

+ On sign up, create a smart account or create an EOA that delegates to a + smart account.{" "} + + Learn more. + +

+
+
+ ); +}; diff --git a/examples/ui-demo/src/components/icons/settings.tsx b/examples/ui-demo/src/components/icons/settings.tsx new file mode 100644 index 0000000000..53a4a45855 --- /dev/null +++ b/examples/ui-demo/src/components/icons/settings.tsx @@ -0,0 +1,21 @@ +import { SVGProps } from "react"; + +export const SettingsIcon = ({ + stroke = "currentColor", + ...props +}: JSX.IntrinsicAttributes & SVGProps) => ( + + + +); diff --git a/examples/ui-demo/src/components/shared/WalletTypeSwitch.tsx b/examples/ui-demo/src/components/shared/WalletTypeSwitch.tsx new file mode 100644 index 0000000000..6535332a83 --- /dev/null +++ b/examples/ui-demo/src/components/shared/WalletTypeSwitch.tsx @@ -0,0 +1,53 @@ +"use client"; + +import { Root, Thumb } from "@radix-ui/react-switch"; +import { forwardRef, ElementRef, ComponentPropsWithoutRef } from "react"; + +import { cn } from "@/lib/utils"; + +const selectedStyles = "text-[#475569]"; +const unselectedStyles = "text-[#020617]"; + +const WalletTypeSwitch = forwardRef< + ElementRef, + ComponentPropsWithoutRef +>(({ className, checked, ...props }, ref) => ( + + +
+
+

+ Smart account +

+
+
+

+ 7702 Smart Account +

+
+
+
+)); +WalletTypeSwitch.displayName = Root.displayName; + +export { WalletTypeSwitch };