From 488a3af154b56cdaba6873fc395c92ccf58c582e Mon Sep 17 00:00:00 2001 From: MananTank Date: Thu, 4 Sep 2025 17:50:50 +0000 Subject: [PATCH] [MNY-106] Playground: Add overview pages for all sections in sidebar (#7977) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ## PR-Codex overview This PR focuses on enhancing the UI components for various sections in a web application, particularly by introducing `OverviewPage` components for different features and updating the layout for better organization and presentation. ### Detailed summary - Updated `className` for `PromptInput` in `chat-container.tsx`. - Added `OverviewPage` components for `Tokens`, `AI`, `Contracts`, `Payments`, `Wallets`, `Transactions`, and `Account Abstraction`. - Introduced `FeatureCard` metadata for various features in `pages-metadata.ts`. - Refactored the main `Page` component to use `FeatureSection` for organized display. - Removed hardcoded feature cards from the main `Page` component. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` ## Summary by CodeRabbit - New Features - Added overview pages for AI, Wallets, Headless Components, Transactions, Contracts, Payments, Tokens, and Account Abstraction. - Introduced reusable OverviewPage and FeatureCard components. - Centralized feature-card metadata for all categories. - Updated navigation to add “Overview” entries and renamed “AI SDK” to “AI SDK Integration”. - Refactor - Home page rewritten to a data-driven layout using shared components and metadata with consistent grid rendering. - Style - Tweaked AI chat input borders and top-edge rounding. --- .../src/app/account-abstraction/page.tsx | 19 ++ .../ai/ai-sdk/components/chat-container.tsx | 2 +- apps/playground-web/src/app/ai/page.tsx | 19 ++ .../playground-web/src/app/contracts/page.tsx | 14 + .../src/app/data/pages-metadata.ts | 297 +++++++++++++++++ apps/playground-web/src/app/navLinks.ts | 43 ++- apps/playground-web/src/app/page.tsx | 299 +++--------------- apps/playground-web/src/app/payments/page.tsx | 19 ++ apps/playground-web/src/app/tokens/page.tsx | 14 + .../src/app/transactions/page.tsx | 14 + .../src/app/wallets/headless/page.tsx | 14 + apps/playground-web/src/app/wallets/page.tsx | 19 ++ .../src/components/blocks/FeatureCard.tsx | 26 ++ .../src/components/blocks/OverviewPage.tsx | 40 +++ 14 files changed, 581 insertions(+), 258 deletions(-) create mode 100644 apps/playground-web/src/app/account-abstraction/page.tsx create mode 100644 apps/playground-web/src/app/ai/page.tsx create mode 100644 apps/playground-web/src/app/contracts/page.tsx create mode 100644 apps/playground-web/src/app/data/pages-metadata.ts create mode 100644 apps/playground-web/src/app/payments/page.tsx create mode 100644 apps/playground-web/src/app/tokens/page.tsx create mode 100644 apps/playground-web/src/app/transactions/page.tsx create mode 100644 apps/playground-web/src/app/wallets/headless/page.tsx create mode 100644 apps/playground-web/src/app/wallets/page.tsx create mode 100644 apps/playground-web/src/components/blocks/FeatureCard.tsx create mode 100644 apps/playground-web/src/components/blocks/OverviewPage.tsx diff --git a/apps/playground-web/src/app/account-abstraction/page.tsx b/apps/playground-web/src/app/account-abstraction/page.tsx new file mode 100644 index 00000000000..d34a77cb8d9 --- /dev/null +++ b/apps/playground-web/src/app/account-abstraction/page.tsx @@ -0,0 +1,19 @@ +import { OverviewPage } from "@/components/blocks/OverviewPage"; +import { SmartAccountIcon } from "../../icons/SmartAccountIcon"; +import { accountAbstractionsFeatureCards } from "../data/pages-metadata"; + +export default function Page() { + return ( + + Transaction infrastructure for gasless or permissioned transactions + utilizing EIP-4337 and 7702 specs + + } + featureCards={accountAbstractionsFeatureCards} + /> + ); +} diff --git a/apps/playground-web/src/app/ai/ai-sdk/components/chat-container.tsx b/apps/playground-web/src/app/ai/ai-sdk/components/chat-container.tsx index 293072b7ebe..d5c536cfc47 100644 --- a/apps/playground-web/src/app/ai/ai-sdk/components/chat-container.tsx +++ b/apps/playground-web/src/app/ai/ai-sdk/components/chat-container.tsx @@ -120,7 +120,7 @@ export function ChatContainer() { + Query onchain data, analyze transactions, prepare contract calls, and + do swaps with AI + + } + featureCards={aiFeatureCards} + /> + ); +} diff --git a/apps/playground-web/src/app/contracts/page.tsx b/apps/playground-web/src/app/contracts/page.tsx new file mode 100644 index 00000000000..f844a390f43 --- /dev/null +++ b/apps/playground-web/src/app/contracts/page.tsx @@ -0,0 +1,14 @@ +import { OverviewPage } from "@/components/blocks/OverviewPage"; +import { ContractIcon } from "../../icons/ContractIcon"; +import { contractsFeatureCards } from "../data/pages-metadata"; + +export default function Page() { + return ( + + ); +} diff --git a/apps/playground-web/src/app/data/pages-metadata.ts b/apps/playground-web/src/app/data/pages-metadata.ts new file mode 100644 index 00000000000..36dca947c5b --- /dev/null +++ b/apps/playground-web/src/app/data/pages-metadata.ts @@ -0,0 +1,297 @@ +import { + ArrowLeftRightIcon, + BlocksIcon, + BotIcon, + BoxIcon, + BracesIcon, + CircleUserIcon, + CreditCardIcon, + DollarSignIcon, + GlobeIcon, + ImageIcon, + LinkIcon, + LockIcon, + PanelTopIcon, + PencilIcon, + PlaneIcon, + RectangleHorizontalIcon, + RssIcon, + ScanTextIcon, + ShieldIcon, + ShoppingBagIcon, + SquircleDashedIcon, + StampIcon, + UserIcon, + WalletCardsIcon, +} from "lucide-react"; +import { InsightIcon } from "../../icons/InsightIcon"; + +export type FeatureCardMetadata = { + icon: React.FC<{ className?: string }>; + title: string; + link: string; + description: string; +}; + +export const walletsFeatureCards: FeatureCardMetadata[] = [ + { + icon: RectangleHorizontalIcon, + title: "Connect Button", + link: "/wallets/sign-in/button", + description: + "Wallet connection component for EOA or email, mobile, social, and passkey logins", + }, + { + icon: PanelTopIcon, + title: "Connect Embed", + link: "/wallets/sign-in/embed", + description: "Embedded component to view balance, get funds, and more", + }, + + { + icon: SquircleDashedIcon, + title: "Headless Connect", + link: "/wallets/sign-in/headless", + description: "Customizable wallet connection components using React hooks", + }, + + { + icon: UserIcon, + title: "In-App Wallets", + link: "/wallets/in-app-wallet", + description: + "Add social login, passkey, phone, or email sign-in to your app", + }, + + { + icon: LockIcon, + title: "Authentication (SIWE)", + link: "/wallets/auth", + description: "Authenticate users to your backend using their wallet", + }, + + { + icon: GlobeIcon, + title: "Social Profiles", + link: "/wallets/social", + description: + "Get user profiles across apps like ENS, Lens, Farcaster, and more", + }, + + { + icon: BoxIcon, + title: "Headless Components", + link: "/wallets/headless", + description: "Components for rendering various wallet related information", + }, +]; + +export const headlessComponentsFeatureCards: FeatureCardMetadata[] = [ + { + icon: CircleUserIcon, + title: "Account Components", + link: "/wallets/headless/account-components", + description: "Components for rendering various account related information", + }, + { + icon: LinkIcon, + title: "Chain Components", + link: "/wallets/headless/chain-components", + description: "Components for rendering various chain related information", + }, + { + icon: WalletCardsIcon, + title: "Wallet Components", + link: "/wallets/headless/wallet-components", + description: "Components for rendering various wallet related information", + }, +]; + +export const transactionsFeatureCards: FeatureCardMetadata[] = [ + { + icon: PlaneIcon, + title: "Airdrop Tokens", + link: "/transactions/airdrop-tokens", + description: + "Airdrop any token with a few lines of code with gas sponsorship, optional.", + }, + { + icon: StampIcon, + title: "Mint NFTs", + link: "/transactions/mint-tokens", + description: + "Gasless and efficient token minting with just a wallet address", + }, + + { + icon: RssIcon, + title: "Webhooks", + link: "/transactions/webhooks", + description: + "Receive real-time notifications for transactions and wallet events.", + }, +]; + +export const contractsFeatureCards: FeatureCardMetadata[] = [ + { + icon: ScanTextIcon, + title: "Read Contract", + link: "/contracts/read", + description: "Read data from any contract on any EVM", + }, + { + icon: PencilIcon, + title: "Write Contract", + link: "/contracts/write", + description: "Send transactions from the connected wallet", + }, + { + icon: BlocksIcon, + title: "Pre-Built Extensions", + link: "/contracts/extensions", + description: "High-level read and write functions", + }, + { + icon: RssIcon, + title: "Listen Contract Events", + link: "/contracts/events", + description: "Subscribe to any contract event", + }, +]; + +export const paymentsFeatureCards: FeatureCardMetadata[] = [ + { + icon: BoxIcon, + title: "Payments UI Components", + link: "/payments/ui-components", + description: "Onramp, swap, and bridge over 1,000+ crypto tokens", + }, + { + icon: ShoppingBagIcon, + title: "Buy Crypto", + link: "/payments/fund-wallet", + description: + "Buy any token with ability to customize theme, amounts, and more", + }, + { + icon: CreditCardIcon, + title: "Checkout", + link: "/payments/commerce", + description: + "Enable crypto payments for services and get notified on each sale", + }, + { + icon: ArrowLeftRightIcon, + title: "Transactions", + link: "/payments/transactions", + description: + "Enable users to pay for onchain transactions with fiat or crypto", + }, + { + icon: BracesIcon, + title: "Payments API", + link: "/payments/backend", + description: "Create customizable UIs or backend flows using the HTTP API", + }, +]; + +export const insightFeatureCards: FeatureCardMetadata[] = [ + { + icon: InsightIcon, + title: "Events", + link: "/insight", + description: "Query contract events on any supported EVM chain", + }, + { + icon: InsightIcon, + title: "Transactions", + link: "/insight", + description: "Query transactions to and from specified recipients", + }, + { + icon: InsightIcon, + title: "Tokens", + link: "/insight", + description: "Query token owners, transfers, prices, and more", + }, + { + icon: InsightIcon, + title: "NFTs", + link: "/insight", + description: + "Query NFT balances, collections, transfers, metadata, and more.", + }, + { + icon: InsightIcon, + title: "Wallets", + link: "/insight", + description: "Query transactions to and from specific wallets", + }, + { + icon: InsightIcon, + title: "Contracts", + link: "/insight", + description: "Query a contract's ABI or metadata", + }, +]; + +export const accountAbstractionsFeatureCards: FeatureCardMetadata[] = [ + { + icon: ShieldIcon, + title: "EIP-4337", + link: "/account-abstraction/eip-4337", + description: + "Implement via a higher-layer mempool using objects and bundlers", + }, + { + icon: ShieldIcon, + title: "EIP-7702", + link: "/account-abstraction/eip-7702", + description: + "Allow EOAs to temporarily behave like smart contracts during txs", + }, + { + icon: ShieldIcon, + title: "EIP-5792", + link: "/account-abstraction/eip-5792", + description: + "Define a standard RPC interface for smart account interactions", + }, + { + icon: ShieldIcon, + title: "Native AA (zkSync)", + link: "/account-abstraction/native-aa", + description: "Native account abstraction available for zkSync chains", + }, +]; + +export const tokensFeatureCards: FeatureCardMetadata[] = [ + { + icon: DollarSignIcon, + title: "Token Components", + link: "/tokens/token-components", + description: + "Headless UI components for rendering token image, name, and symbol", + }, + { + icon: ImageIcon, + title: "NFT Components", + link: "/tokens/nft-components", + description: "Headless UI components for rendering NFT Media and metadata", + }, +]; + +export const aiFeatureCards: FeatureCardMetadata[] = [ + { + icon: BotIcon, + title: "Blockchain LLM", + link: "/ai/chat", + description: "thirdweb AI demo chat application", + }, + { + icon: BotIcon, + title: "AI SDK Integration", + link: "/ai/ai-sdk", + description: "Use the thirdweb blockchain models with the Vercel AI SDK", + }, +]; diff --git a/apps/playground-web/src/app/navLinks.ts b/apps/playground-web/src/app/navLinks.ts index 081a9c24ddf..27afc614c30 100644 --- a/apps/playground-web/src/app/navLinks.ts +++ b/apps/playground-web/src/app/navLinks.ts @@ -16,13 +16,18 @@ const ai: ShadcnSidebarLink = { icon: BotIcon, }, links: [ + { + href: "/ai", + label: "Overview", + exactMatch: true, + }, { href: "/ai/chat", label: "Blockchain LLM", }, { href: "/ai/ai-sdk", - label: "AI SDK", + label: "AI SDK Integration", }, ], }; @@ -33,6 +38,11 @@ const wallets: ShadcnSidebarLink = { icon: WalletProductIcon, }, links: [ + { + label: "Overview", + href: "/wallets", + exactMatch: true, + }, { href: "/wallets/sign-in/button", label: "Connect Button", @@ -61,12 +71,16 @@ const wallets: ShadcnSidebarLink = { href: "/wallets/social", label: "Social Profiles", }, - { subMenu: { label: "Headless Components", }, links: [ + { + label: "Overview", + href: "/wallets/headless", + exactMatch: true, + }, { href: "/wallets/headless/account-components", label: "Account Components", @@ -90,6 +104,11 @@ const contracts: ShadcnSidebarLink = { icon: ContractIcon, }, links: [ + { + label: "Overview", + href: "/contracts", + exactMatch: true, + }, { href: "/contracts/read", label: "Read Contract", @@ -115,6 +134,11 @@ const tokens: ShadcnSidebarLink = { icon: TokenIcon, }, links: [ + { + label: "Overview", + href: "/tokens", + exactMatch: true, + }, { href: "/tokens/token-components", label: "Token Components", @@ -132,6 +156,11 @@ const accountAbstractions: ShadcnSidebarLink = { icon: SmartAccountIcon, }, links: [ + { + label: "Overview", + href: "/account-abstraction", + exactMatch: true, + }, { href: "/account-abstraction/eip-4337", label: "EIP-4337", @@ -157,6 +186,11 @@ const payments: ShadcnSidebarLink = { icon: PayIcon, }, links: [ + { + label: "Overview", + href: "/payments", + exactMatch: true, + }, { href: "/payments/ui-components", label: "UI Components", @@ -186,6 +220,11 @@ const transactions: ShadcnSidebarLink = { icon: ArrowLeftRightIcon, }, links: [ + { + label: "Overview", + href: "/transactions", + exactMatch: true, + }, { href: "/transactions/airdrop-tokens", label: "Airdrop Tokens", diff --git a/apps/playground-web/src/app/page.tsx b/apps/playground-web/src/app/page.tsx index 451c955bd55..e618a19155b 100644 --- a/apps/playground-web/src/app/page.tsx +++ b/apps/playground-web/src/app/page.tsx @@ -1,26 +1,15 @@ -import { - ArrowLeftRightIcon, - BlocksIcon, - BoxIcon, - BracesIcon, - CreditCardIcon, - GlobeIcon, - LockIcon, - PanelTopIcon, - PencilIcon, - PlaneIcon, - RectangleHorizontalIcon, - RssIcon, - ScanTextIcon, - ShieldIcon, - ShoppingBagIcon, - SquircleDashedIcon, - StampIcon, - UserIcon, -} from "lucide-react"; -import Link from "next/link"; -import { InsightIcon } from "../icons/InsightIcon"; +import { FeatureCard } from "@/components/blocks/FeatureCard"; import { ThirdwebIcon } from "../icons/ThirdwebMiniLogo"; +import { + accountAbstractionsFeatureCards, + aiFeatureCards, + contractsFeatureCards, + type FeatureCardMetadata, + insightFeatureCards, + paymentsFeatureCards, + transactionsFeatureCards, + walletsFeatureCards, +} from "./data/pages-metadata"; export default function Page() { return ( @@ -48,247 +37,47 @@ export default function Page() {
- {/* Wallets Section */} -
- -
- - - - - - -
-
- - {/* Transactions Section */} -
- -
- - - -
-
- - {/* Contracts Section */} -
- -
- - - - -
-
- - {/* Payments Section */} -
- -
- - - - - -
-
- - {/* Insight Section */} -
- -
- - - - - - -
-
- - {/* Account Abstraction Section */} -
- -
- - - - -
-
+ + + + + + +
); } -function SectionTitle(props: { label: string }) { - return ( -

- {props.label} -

- ); -} - -function FeatureCard(props: { +function FeatureSection(props: { + featureCards: FeatureCardMetadata[]; title: string; - description: string; - icon: React.FC<{ className?: string }>; - href: string; // todo make this required }) { return ( -
-
-
- -
+
+

+ {props.title} +

+
+ {props.featureCards.slice(0, 6).map((card) => ( + + ))}
-

- - {props.title} - -

-

{props.description}

-
+ ); } diff --git a/apps/playground-web/src/app/payments/page.tsx b/apps/playground-web/src/app/payments/page.tsx new file mode 100644 index 00000000000..546ba938804 --- /dev/null +++ b/apps/playground-web/src/app/payments/page.tsx @@ -0,0 +1,19 @@ +import { OverviewPage } from "@/components/blocks/OverviewPage"; +import { PayIcon } from "../../icons/PayIcon"; +import { paymentsFeatureCards } from "../data/pages-metadata"; + +export default function Page() { + return ( + + Allow developers and users to receive and spend any token on any EVM + chain + + } + featureCards={paymentsFeatureCards} + /> + ); +} diff --git a/apps/playground-web/src/app/tokens/page.tsx b/apps/playground-web/src/app/tokens/page.tsx new file mode 100644 index 00000000000..6beba5b740d --- /dev/null +++ b/apps/playground-web/src/app/tokens/page.tsx @@ -0,0 +1,14 @@ +import { OverviewPage } from "@/components/blocks/OverviewPage"; +import { TokenIcon } from "../../icons/TokenIcon"; +import { tokensFeatureCards } from "../data/pages-metadata"; + +export default function Page() { + return ( + Headless UI components for rendering tokens and NFTs} + featureCards={tokensFeatureCards} + /> + ); +} diff --git a/apps/playground-web/src/app/transactions/page.tsx b/apps/playground-web/src/app/transactions/page.tsx new file mode 100644 index 00000000000..83ce7024247 --- /dev/null +++ b/apps/playground-web/src/app/transactions/page.tsx @@ -0,0 +1,14 @@ +import { ArrowLeftRightIcon } from "lucide-react"; +import { OverviewPage } from "../../components/blocks/OverviewPage"; +import { transactionsFeatureCards } from "../data/pages-metadata"; + +export default function Page() { + return ( + + ); +} diff --git a/apps/playground-web/src/app/wallets/headless/page.tsx b/apps/playground-web/src/app/wallets/headless/page.tsx new file mode 100644 index 00000000000..86856c5c452 --- /dev/null +++ b/apps/playground-web/src/app/wallets/headless/page.tsx @@ -0,0 +1,14 @@ +import { BoxIcon } from "lucide-react"; +import { OverviewPage } from "@/components/blocks/OverviewPage"; +import { headlessComponentsFeatureCards } from "../../data/pages-metadata"; + +export default function Page() { + return ( + + ); +} diff --git a/apps/playground-web/src/app/wallets/page.tsx b/apps/playground-web/src/app/wallets/page.tsx new file mode 100644 index 00000000000..efbb9068da5 --- /dev/null +++ b/apps/playground-web/src/app/wallets/page.tsx @@ -0,0 +1,19 @@ +import { OverviewPage } from "@/components/blocks/OverviewPage"; +import { WalletProductIcon } from "../../icons/WalletProductIcon"; +import { walletsFeatureCards } from "../data/pages-metadata"; + +export default function Page() { + return ( + + Create, onboard, and manage user identities in applications through + in-app wallets and server wallets. + + } + featureCards={walletsFeatureCards} + /> + ); +} diff --git a/apps/playground-web/src/components/blocks/FeatureCard.tsx b/apps/playground-web/src/components/blocks/FeatureCard.tsx new file mode 100644 index 00000000000..93a939d9b08 --- /dev/null +++ b/apps/playground-web/src/components/blocks/FeatureCard.tsx @@ -0,0 +1,26 @@ +import Link from "next/link"; + +export function FeatureCard(props: { + title: string; + description: string; + icon: React.FC<{ className?: string }>; + href: string; +}) { + return ( +
+
+
+ +
+
+

+ + {props.title} + +

+

+ {props.description} +

+
+ ); +} diff --git a/apps/playground-web/src/components/blocks/OverviewPage.tsx b/apps/playground-web/src/components/blocks/OverviewPage.tsx new file mode 100644 index 00000000000..9d7733e9591 --- /dev/null +++ b/apps/playground-web/src/components/blocks/OverviewPage.tsx @@ -0,0 +1,40 @@ +import type { FeatureCardMetadata } from "@/app/data/pages-metadata"; +import { FeatureCard } from "@/components/blocks/FeatureCard"; + +export function OverviewPage(props: { + featureCards: FeatureCardMetadata[]; + title: string; + description: React.ReactNode; + icon: React.FC<{ className?: string }>; +}) { + return ( +
+
+
+
+
+ +
+
+

+ {props.title} +

+

+ {props.description} +

+
+
+
+ {props.featureCards.map((card) => ( + + ))} +
+
+ ); +}