From a054a3f9bc3ee4bb464ecaf6f6c6a9cc883e9b16 Mon Sep 17 00:00:00 2001 From: Steve Date: Fri, 5 Sep 2025 14:51:56 -0400 Subject: [PATCH 01/10] chore: fixed telegram link --- src/app/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index 0b740ca1..dccb735a 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -445,7 +445,7 @@ export default function HomePage() { Date: Fri, 5 Sep 2025 14:59:06 -0400 Subject: [PATCH 02/10] fix: fixed mermaid graphs --- .../building-adapters.mdx | 23 ++----------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/content/contracts-ui-builder/building-adapters.mdx b/content/contracts-ui-builder/building-adapters.mdx index c39251da..6d634662 100644 --- a/content/contracts-ui-builder/building-adapters.mdx +++ b/content/contracts-ui-builder/building-adapters.mdx @@ -18,14 +18,6 @@ This decoupling is achieved through the `ContractAdapter` interface, defined in * **Network-Aware Adapters**: An adapter instance is not generic; it is **instantiated with a specific `NetworkConfig` object**. This makes the instance aware of its target network (e.g., Ethereum Mainnet vs. Sepolia Testnet), including its RPC endpoints, explorer URLs, and chain identifiers. The adapter stores this `networkConfig` internally and uses it for all network-dependent operations. ```mermaid -%%init: { - 'theme': 'base', - 'themeVariables': { - 'background': '#ffffff', - 'mainBkg': '#ffffff', - 'primaryBorderColor': '#cccccc' - -}}%% graph TB subgraph "Chain-Agnostic Core" Builder["Builder Package
(Main Application)"] @@ -245,16 +237,8 @@ The functions `resolveRpcUrl` and `resolveExplorerConfig` in the EVM adapter pro 6. **Build and Test**: Build your new package and the main builder app. Add unit and integration tests to ensure your adapter functions correctly within the larger system. ```mermaid -%%init: { - 'theme': 'base', - 'themeVariables': { - 'background': '#ffffff', - 'mainBkg': '#ffffff', - 'primaryBorderColor': '#cccccc' - -}}%% graph TD - A[Start: Add Support for New Chain] --> BCreate New Package: packages/adapter-name + A[Start: Add Support for New Chain] --> B[Create New Package: packages/adapter-name] B --> C[Define NetworkConfig Objects in src/networks] C --> D[Implement the ContractAdapter Interface in src/adapter.ts] @@ -272,13 +256,10 @@ graph TD D --> D4 D --> D5 - D5 --> ERegister Adapter in Builder: packages/builder/src/core/ecosystemManager.ts + D5 --> E[Register Adapter in Builder: packages/builder/src/core/ecosystemManager.ts] E --> F[Add to ecosystemRegistry] E --> G[Add dynamic import to loadAdapterPackageModule] G --> H[Build and Test] H --> I[End: New Adapter Integrated] - - style A fill:#000,stroke:#333,stroke-width:2px - style I fill:#000,stroke:#333,stroke-width:2px ``` From bf20027a5a9cac9ccac7ab5685d81125e68214cb Mon Sep 17 00:00:00 2001 From: Steve Date: Fri, 5 Sep 2025 15:16:31 -0400 Subject: [PATCH 03/10] chore: adjusted navigation --- src/navigation/ethereum-evm.json | 388 ++++++++++++++++--------------- 1 file changed, 195 insertions(+), 193 deletions(-) diff --git a/src/navigation/ethereum-evm.json b/src/navigation/ethereum-evm.json index a2c53d0c..7204838c 100644 --- a/src/navigation/ethereum-evm.json +++ b/src/navigation/ethereum-evm.json @@ -885,14 +885,206 @@ } ] }, + { + "type": "page", + "name": "Wizard", + "url": "/wizard" + }, + { + "type": "folder", + "name": "Learn", + "children": [ + { + "type": "page", + "name": "Overview", + "url": "/contracts/v5.x/learn" + }, + { + "type": "page", + "name": "Setting up a Node project", + "url": "/contracts/v5.x/learn/setting-up-a-node-project" + }, + { + "type": "page", + "name": "Developing smart contracts", + "url": "/contracts/v5.x/learn/developing-smart-contracts" + }, + { + "type": "page", + "name": "Deploying and interacting", + "url": "/contracts/v5.x/learn/deploying-and-interacting" + }, + { + "type": "page", + "name": "Writing automated tests", + "url": "/contracts/v5.x/learn/writing-automated-tests" + }, + { + "type": "page", + "name": "Connecting to public test networks", + "url": "/contracts/v5.x/learn/connecting-to-public-test-networks" + }, + { + "type": "page", + "name": "Upgrading smart contracts", + "url": "/contracts/v5.x/learn/upgrading-smart-contracts" + }, + { + "type": "page", + "name": "Preparing for mainnet", + "url": "/contracts/v5.x/learn/preparing-for-mainnet" + } + ] + }, { "type": "separator", "name": "Tools" }, { - "type": "page", - "name": "Wizard", - "url": "/wizard" + "type": "folder", + "name": "Relayer", + "children": [ + { + "type": "page", + "name": "Overview", + "url": "/openzeppelin-relayer" + }, + { + "type": "page", + "name": "Quickstart", + "url": "/openzeppelin-relayer/quickstart" + }, + { + "type": "folder", + "name": "Configuration", + "index": { + "type": "page", + "name": "Overview", + "url": "/openzeppelin-relayer/configuration" + }, + "children": [ + { + "type": "page", + "name": "Signers", + "url": "/openzeppelin-relayer/configuration/signers" + }, + { + "type": "page", + "name": "Network Configuration", + "url": "/openzeppelin-relayer/network_configuration" + }, + { + "type": "page", + "name": "Storage Configuration", + "url": "/openzeppelin-relayer/configuration/storage" + } + ] + }, + { + "type": "page", + "name": "EVM Integration", + "url": "/openzeppelin-relayer/evm" + }, + { + "type": "page", + "name": "Solana Integration", + "url": "/openzeppelin-relayer/solana" + }, + { + "type": "page", + "name": "Stellar Integration", + "url": "/openzeppelin-relayer/stellar" + }, + { + "type": "page", + "name": "API Reference", + "url": "https://release-v1-1-0--openzeppelin-relayer.netlify.app/api_docs.html", + "external": true + }, + { + "type": "page", + "name": "Project Structure", + "url": "/openzeppelin-relayer/structure" + }, + { + "type": "page", + "name": "Project Roadmap", + "url": "/openzeppelin-relayer/roadmap" + }, + { + "type": "page", + "name": "Plugins", + "url": "/openzeppelin-relayer/plugins" + }, + { + "type": "page", + "name": "Changelog", + "url": "/openzeppelin-relayer/changelog" + }, + { + "type": "page", + "name": "Technical Rust Documentation", + "url": "https://release-v1-1-0--openzeppelin-relayer.netlify.app/openzeppelin_relayer/", + "external": true + } + ] + }, + { + "type": "folder", + "name": "Monitor", + "children": [ + { + "type": "page", + "name": "Quickstart", + "url": "/openzeppelin-monitor/quickstart" + }, + { + "type": "page", + "name": "Architecture Guide", + "url": "/openzeppelin-monitor/architecture" + }, + { + "type": "page", + "name": "Project Structure", + "url": "/openzeppelin-monitor/project-structure" + }, + { + "type": "page", + "name": "RPC Client", + "url": "/openzeppelin-monitor/rpc" + }, + { + "type": "page", + "name": "Custom scripts", + "url": "/openzeppelin-monitor/scripts" + }, + { + "type": "page", + "name": "Error Handling", + "url": "/openzeppelin-monitor/error" + }, + { + "type": "page", + "name": "Testing", + "url": "/openzeppelin-monitor/testing" + }, + { + "type": "page", + "name": "Contribution guidelines", + "url": "/openzeppelin-monitor/contribution" + }, + { + "type": "page", + "name": "Changelog", + "url": "/openzeppelin-monitor/changelog" + }, + { + "type": "page", + "name": "Technical Rust Documentation", + "url": "https://release-v1-0-0--openzeppelin-monitor.netlify.app/openzeppelin_monitor/", + "external": true + } + ] }, { "type": "folder", @@ -1139,195 +1331,5 @@ "url": "/defender/changelog" } ] - }, - { - "type": "folder", - "name": "Monitor", - "children": [ - { - "type": "page", - "name": "Quickstart", - "url": "/openzeppelin-monitor/quickstart" - }, - { - "type": "page", - "name": "Architecture Guide", - "url": "/openzeppelin-monitor/architecture" - }, - { - "type": "page", - "name": "Project Structure", - "url": "/openzeppelin-monitor/project-structure" - }, - { - "type": "page", - "name": "RPC Client", - "url": "/openzeppelin-monitor/rpc" - }, - { - "type": "page", - "name": "Custom scripts", - "url": "/openzeppelin-monitor/scripts" - }, - { - "type": "page", - "name": "Error Handling", - "url": "/openzeppelin-monitor/error" - }, - { - "type": "page", - "name": "Testing", - "url": "/openzeppelin-monitor/testing" - }, - { - "type": "page", - "name": "Contribution guidelines", - "url": "/openzeppelin-monitor/contribution" - }, - { - "type": "page", - "name": "Changelog", - "url": "/openzeppelin-monitor/changelog" - }, - { - "type": "page", - "name": "Technical Rust Documentation", - "url": "https://release-v1-0-0--openzeppelin-monitor.netlify.app/openzeppelin_monitor/", - "external": true - } - ] - }, - { - "type": "folder", - "name": "Relayer", - "children": [ - { - "type": "page", - "name": "Overview", - "url": "/openzeppelin-relayer" - }, - { - "type": "page", - "name": "Quickstart", - "url": "/openzeppelin-relayer/quickstart" - }, - { - "type": "folder", - "name": "Configuration", - "index": { - "type": "page", - "name": "Overview", - "url": "/openzeppelin-relayer/configuration" - }, - "children": [ - { - "type": "page", - "name": "Signers", - "url": "/openzeppelin-relayer/configuration/signers" - }, - { - "type": "page", - "name": "Network Configuration", - "url": "/openzeppelin-relayer/network_configuration" - }, - { - "type": "page", - "name": "Storage Configuration", - "url": "/openzeppelin-relayer/configuration/storage" - } - ] - }, - { - "type": "page", - "name": "EVM Integration", - "url": "/openzeppelin-relayer/evm" - }, - { - "type": "page", - "name": "Solana Integration", - "url": "/openzeppelin-relayer/solana" - }, - { - "type": "page", - "name": "Stellar Integration", - "url": "/openzeppelin-relayer/stellar" - }, - { - "type": "page", - "name": "API Reference", - "url": "https://release-v1-1-0--openzeppelin-relayer.netlify.app/api_docs.html", - "external": true - }, - { - "type": "page", - "name": "Project Structure", - "url": "/openzeppelin-relayer/structure" - }, - { - "type": "page", - "name": "Project Roadmap", - "url": "/openzeppelin-relayer/roadmap" - }, - { - "type": "page", - "name": "Plugins", - "url": "/openzeppelin-relayer/plugins" - }, - { - "type": "page", - "name": "Changelog", - "url": "/openzeppelin-relayer/changelog" - }, - { - "type": "page", - "name": "Technical Rust Documentation", - "url": "https://release-v1-1-0--openzeppelin-relayer.netlify.app/openzeppelin_relayer/", - "external": true - } - ] - }, - { - "type": "separator", - "name": "Guides" - }, - { - "type": "page", - "name": "Overview", - "url": "/contracts/v5.x/learn" - }, - { - "type": "page", - "name": "Setting up a Node project", - "url": "/contracts/v5.x/learn/setting-up-a-node-project" - }, - { - "type": "page", - "name": "Developing smart contracts", - "url": "/contracts/v5.x/learn/developing-smart-contracts" - }, - { - "type": "page", - "name": "Deploying and interacting", - "url": "/contracts/v5.x/learn/deploying-and-interacting" - }, - { - "type": "page", - "name": "Writing automated tests", - "url": "/contracts/v5.x/learn/writing-automated-tests" - }, - { - "type": "page", - "name": "Connecting to public test networks", - "url": "/contracts/v5.x/learn/connecting-to-public-test-networks" - }, - { - "type": "page", - "name": "Upgrading smart contracts", - "url": "/contracts/v5.x/learn/upgrading-smart-contracts" - }, - { - "type": "page", - "name": "Preparing for mainnet", - "url": "/contracts/v5.x/learn/preparing-for-mainnet" } ] From 10a24a56dfa231a5c9721f8f968796e4a8ce76e4 Mon Sep 17 00:00:00 2001 From: Steve Date: Fri, 5 Sep 2025 15:23:23 -0400 Subject: [PATCH 04/10] chore: update ecosystem product naming conventions --- src/app/page.tsx | 2 +- src/navigation/arbitrum-stylus.json | 2 +- src/navigation/ethereum-evm.json | 8 ++++---- src/navigation/midnight.json | 2 +- src/navigation/polkadot.json | 2 +- src/navigation/starknet.json | 2 +- src/navigation/uniswap.json | 2 +- src/navigation/zama.json | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index dccb735a..1e3d5350 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -251,7 +251,7 @@ export default function HomePage() { className="relative overflow-hidden hover:border-cyan-500 transition-colors before:absolute before:top-0 before:left-0 before:right-0 before:h-0.5 before:bg-gradient-to-r before:from-cyan-600 before:to-cyan-400 before:opacity-0 hover:before:opacity-100 before:transition-opacity" /> } diff --git a/src/navigation/arbitrum-stylus.json b/src/navigation/arbitrum-stylus.json index f1bd1b31..186e7a40 100644 --- a/src/navigation/arbitrum-stylus.json +++ b/src/navigation/arbitrum-stylus.json @@ -1,7 +1,7 @@ [ { "type": "separator", - "name": "Contracts Stylus" + "name": "Arbitrum Stylus Contracts" }, { "type": "page", diff --git a/src/navigation/ethereum-evm.json b/src/navigation/ethereum-evm.json index 7204838c..3ebffa0d 100644 --- a/src/navigation/ethereum-evm.json +++ b/src/navigation/ethereum-evm.json @@ -1,11 +1,11 @@ [ { "type": "separator", - "name": "Contracts" + "name": "Solidity Contracts" }, { "type": "folder", - "name": "Solidity Contracts", + "name": "OpenZeppelin Contracts", "children": [ { "type": "page", @@ -779,7 +779,7 @@ }, { "type": "folder", - "name": "Solidity Community Contracts", + "name": "Community Contracts", "index": { "type": "page", "name": "Overview", @@ -821,7 +821,7 @@ }, { "type": "folder", - "name": "Solidity Upgrade Plugins", + "name": "Upgrade Plugins", "index": { "type": "page", "name": "Overview", diff --git a/src/navigation/midnight.json b/src/navigation/midnight.json index 51713774..f36ff6f2 100644 --- a/src/navigation/midnight.json +++ b/src/navigation/midnight.json @@ -1,7 +1,7 @@ [ { "type": "separator", - "name": "Contracts" + "name": "Midnight Contracts" }, { "type": "page", diff --git a/src/navigation/polkadot.json b/src/navigation/polkadot.json index 5eaaef91..0fa7ad81 100644 --- a/src/navigation/polkadot.json +++ b/src/navigation/polkadot.json @@ -1,7 +1,7 @@ [ { "type": "separator", - "name": "Substrate Runtimes" + "name": "Polkadot Substrate Runtimes" }, { "type": "page", diff --git a/src/navigation/starknet.json b/src/navigation/starknet.json index 59359e56..cbeb50f3 100644 --- a/src/navigation/starknet.json +++ b/src/navigation/starknet.json @@ -1,7 +1,7 @@ [ { "type": "separator", - "name": "Contracts" + "name": "Starknet Contracts" }, { "type": "page", diff --git a/src/navigation/uniswap.json b/src/navigation/uniswap.json index b326ee59..ca20c64d 100644 --- a/src/navigation/uniswap.json +++ b/src/navigation/uniswap.json @@ -1,7 +1,7 @@ [ { "type": "separator", - "name": "Uniswap Hooks" + "name": "Uniswap Hooks Contracts" }, { "type": "page", diff --git a/src/navigation/zama.json b/src/navigation/zama.json index 67632dc2..547b2c31 100644 --- a/src/navigation/zama.json +++ b/src/navigation/zama.json @@ -1,7 +1,7 @@ [ { "type": "separator", - "name": "Contracts" + "name": "Zama FHEVM Contracts" }, { "type": "page", From 2f57aec294ba93bb8a6dc3f900dff421a9db0681 Mon Sep 17 00:00:00 2001 From: Steve Date: Fri, 5 Sep 2025 16:05:10 -0400 Subject: [PATCH 05/10] chore: updated homepage --- src/app/global.css | 9 + src/app/layout.config.tsx | 70 ++--- src/app/page.tsx | 505 ++++++++++------------------------ src/components/home-cards.tsx | 245 +++++++++++++++++ 4 files changed, 442 insertions(+), 387 deletions(-) create mode 100644 src/components/home-cards.tsx diff --git a/src/app/global.css b/src/app/global.css index e317592e..80fd28a1 100644 --- a/src/app/global.css +++ b/src/app/global.css @@ -121,3 +121,12 @@ @apply bg-background text-foreground; } } + +@keyframes shimmer { + 0% { + background-position: -100% 0; + } + 100% { + background-position: 100% 0; + } +} diff --git a/src/app/layout.config.tsx b/src/app/layout.config.tsx index a9c2b105..dd2ff04f 100644 --- a/src/app/layout.config.tsx +++ b/src/app/layout.config.tsx @@ -13,73 +13,79 @@ export const baseOptions: BaseLayoutProps = { title: ( <> OpenZeppelin Logo + diff --git a/src/app/page.tsx b/src/app/page.tsx index 1e3d5350..15577969 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,9 +1,7 @@ -import { Card } from "fumadocs-ui/components/card"; import { HomeLayout } from "fumadocs-ui/layouts/home"; import { ActivityIcon, ArrowUpIcon, - ExternalLinkIcon, GamepadIcon, LibraryIcon, MessageCircleIcon, @@ -24,12 +22,19 @@ import { UniswapIcon, ZamaIcon, } from "@/components/icons"; +import { + HeroCard, + FeatureCard, + EcosystemCard, + CommunityCard, + BannerCard, +} from "@/components/home-cards"; import { baseOptions } from "./layout.config"; export default function HomePage() { return ( -
+
{/* Hero Section */}

@@ -40,155 +45,89 @@ export default function HomePage() {

- {/* Two Column Tool Boxes */} -
- {/* Smart Contracts Box */} -
-
-

- OpenZeppelin Smart Contracts -

-

- Battle-tested libraries and tools for smart contract development -

-
-
+ {/* Smart Contracts Section */} +
+
+ Smart Contracts +
+ + {/* Primary Hero: OpenZeppelin Contracts */} + } + title="OpenZeppelin Solidity Contracts" + description="The world's most popular library of Solidity contracts for Ethereum and EVM blockchains. Battle-tested, community-reviewed, and trusted by thousands of projects worldwide." + /> + + {/* Supporting Cards */} +
+ } + title="Upgrades Plugins" + description="Deploy and manage upgradeable contracts with built-in safety checks and best practices" + /> + + } + title="Contracts Wizard" + description="Interactive smart contract generator with security best practices built-in" + /> + + } + title="Contracts MCP" + description="AI-powered assistant for smart contract development and security analysis" + />
+
- {/* Open Source Tools Box */} -
-
-

Open Source Tools

-

- Tools for building, testing, and managing contracts in - production -

-
- + {/* Divider */} +
+ + {/* Open Source Tools Section */} +
+
+ + Open Source Tools +
+ + {/* Dual Heroes: Monitor and Relayer */} +
+ } + title="Relayer" + description="Enable gasless transactions and automate smart contract operations. Build better user experiences with meta-transactions and scheduled executions." + glowColor="tools" + /> + + } + title="Monitor" + description="Real-time monitoring and alerting for your smart contracts. Get notified about important events, transactions, and state changes across multiple chains." + glowColor="tools" + /> +
+ + {/* Minor Tools */} +
+ } + title="UI Builder" + description="Create user interfaces for deployed contracts" + /> + + } + title="Defender" + description="Secure operations platform" + />
@@ -196,7 +135,7 @@ export default function HomePage() {
{/* Blockchains and Developer Ecosystems */} -
+

Blockchains and Developer Ecosystems @@ -208,260 +147,116 @@ export default function HomePage() {

- } title="Ethereum & EVM" description="Solidity smart contracts for Ethereum and EVM-compatible chains" - icon={} - className="relative overflow-hidden hover:border-blue-500 transition-colors before:absolute before:top-0 before:left-0 before:right-0 before:h-0.5 before:bg-gradient-to-r before:from-blue-600 before:to-blue-400 before:opacity-0 hover:before:opacity-100 before:transition-opacity" + glowColor="evm" /> - } title="Starknet" description="Essential contracts library written in Cairo for Starknet" - icon={} - className="relative overflow-hidden hover:border-orange-500 transition-colors before:absolute before:top-0 before:left-0 before:right-0 before:h-0.5 before:bg-gradient-to-r before:from-orange-600 before:to-orange-400 before:opacity-0 hover:before:opacity-100 before:transition-opacity" + glowColor="starknet" /> - } title="Arbitrum Stylus" description="Essential contracts library for Arbitrum Stylus written in Rust" - icon={} - className="relative overflow-hidden hover:border-red-500 transition-colors before:absolute before:top-0 before:left-0 before:right-0 before:h-0.5 before:bg-gradient-to-r before:from-red-600 before:to-red-400 before:opacity-0 hover:before:opacity-100 before:transition-opacity" + glowColor="rust" /> - } title="Uniswap Hooks" description="Advanced Uniswap V4 hooks in Solidity" - icon={} - className="relative overflow-hidden hover:border-blue-500 transition-colors before:absolute before:top-0 before:left-0 before:right-0 before:h-0.5 before:bg-gradient-to-r before:from-blue-600 before:to-blue-400 before:opacity-0 hover:before:opacity-100 before:transition-opacity" - /> - } - className="relative overflow-hidden hover:border-yellow-500 transition-colors before:absolute before:top-0 before:left-0 before:right-0 before:h-0.5 before:bg-gradient-to-r before:from-yellow-600 before:to-yellow-400 before:opacity-0 hover:before:opacity-100 before:transition-opacity" + glowColor="uniswap" /> - } title="Stellar" description="Soroban contracts library for Stellar" - icon={} - className="relative overflow-hidden hover:border-cyan-500 transition-colors before:absolute before:top-0 before:left-0 before:right-0 before:h-0.5 before:bg-gradient-to-r before:from-cyan-600 before:to-cyan-400 before:opacity-0 hover:before:opacity-100 before:transition-opacity" + glowColor="stellar" /> - } title="Midnight" description="Privacy-preserving smart contracts for Midnight blockchain" - icon={} - className="relative overflow-hidden hover:border-purple-500 transition-colors before:absolute before:top-0 before:left-0 before:right-0 before:h-0.5 before:bg-gradient-to-r before:from-purple-600 before:to-purple-400 before:opacity-0 hover:before:opacity-100 before:transition-opacity" + glowColor="midnight" /> - } title="Polkadot" description="ink! smart contracts for Polkadot and Substrate chains" - icon={} - className="relative overflow-hidden hover:border-pink-500 transition-colors before:absolute before:top-0 before:left-0 before:right-0 before:h-0.5 before:bg-gradient-to-r before:from-pink-600 before:to-pink-400 before:opacity-0 hover:before:opacity-100 before:transition-opacity" + glowColor="polkadot" + /> + + } + title="Zama FHEVM" + description="Fully homomorphic encryption contracts for confidential smart contracts" + glowColor="zama" />
- {/* Learn Section */} -
+ {/* Learn & Play Section */} +
-

Learn

+

Learn & Play

- Comprehensive guides for every step of your development journey + Master smart contract security through interactive challenges

- {/* First row: 4 foundational guides */} - - - {/* Second row: 3 advanced guides */} - - - {/* Ethernaut CTF Banner */} - -
- -
-
-
- Interactive Learning -
-

Ethernaut CTF

-

- Learn smart contract security by hacking! A Web3/Solidity based - capture-the-flag game where each level is a smart contract that - needs to be 'hacked'. Perfect for learning vulnerabilities and - security best practices through hands-on challenges. -

-
-
-
+ icon={} + title="Ethernaut CTF" + description="Learn smart contract security by hacking! A Web3/Solidity based capture-the-flag game where each level is a smart contract that needs to be 'hacked'. Perfect for learning vulnerabilities and security best practices through hands-on challenges." + badge="Interactive Learning" + />
{/* Community & Support */} -
+
-

Community & Support

+

+ Community & Support +

Connect with the community for technical discussions and support

- -
-
- -
-

Forum

-
-

- Deep technical discussions, architectural questions, and - detailed support. Best place for in-depth conversations about - smart contract development, security patterns, and - implementation details. -

-
+ icon={} + title="Forum" + description="Deep technical discussions, architectural questions, and detailed support. Best place for in-depth conversations about smart contract development, security patterns, and implementation details." + /> - -
-
- -
-

Telegram

-
-

- Quick questions, community support, and real-time chat. Join our - active community for faster responses, general help, - announcements, and casual discussions about OpenZeppelin tools. -

-
+ icon={} + title="Telegram" + description="Quick questions, community support, and real-time chat. Join our active community for faster responses, general help, announcements, and casual discussions about OpenZeppelin tools." + />
diff --git a/src/components/home-cards.tsx b/src/components/home-cards.tsx new file mode 100644 index 00000000..e3cbf27b --- /dev/null +++ b/src/components/home-cards.tsx @@ -0,0 +1,245 @@ +import type * as React from "react"; +import { cn } from "@/lib/utils"; + +interface GlowColor { + from: string; + to: string; +} + +interface HeroCardProps { + href: string; + icon: React.ReactNode; + title: string; + description: string; + glowColor?: GlowColor; + className?: string; +} + +interface FeatureCardProps { + href: string; + icon: React.ReactNode; + title: string; + description: string; + glowColor?: GlowColor; + className?: string; +} + +interface EcosystemCardProps { + href: string; + icon: React.ReactNode; + title: string; + description: string; + className?: string; +} + +interface CommunityCardProps { + href: string; + icon: React.ReactNode; + title: string; + description: string; + className?: string; +} + +interface BannerCardProps { + href: string; + icon: React.ReactNode; + title: string; + description: string; + badge?: string; + className?: string; +} + +// Primary Hero Card - Large card with gradient background +function HeroCard({ + href, + icon, + title, + description, + glowColor = "primary-hero", + className, +}: Omit & { glowColor?: string }) { + const glowClasses = { + "primary-hero": + "before:bg-gradient-to-r before:from-[#4945ff] before:to-[#627eea]", + }; + + return ( + +
+
+ {icon} +
+
+

{title}

+

{description}

+
+
+
+
+ ); +} + +// Feature Card - Standard card with icon + title horizontal, description below +function FeatureCard({ + href, + icon, + title, + description, + glowColor = "tools", + className, +}: Omit & { glowColor?: string }) { + const glowClasses = { + tools: "before:bg-gradient-to-r before:from-[#4F55FA] before:to-[#0AC2FF]", + evm: "before:bg-gradient-to-r before:from-[#627eea] before:to-[#4945ff]", + starknet: + "before:bg-gradient-to-r before:from-[#0C0C4F] before:to-[#EC796B]", + rust: "before:bg-gradient-to-r before:from-[#ce422b] before:to-[#f74c00]", + zk: "before:bg-gradient-to-r before:from-[#10b981] before:to-[#34d399]", + stellar: + "before:bg-gradient-to-r before:from-[#00d4ff] before:to-[#0099ff]", + midnight: + "before:bg-gradient-to-r before:from-[#8b5cf6] before:to-[#a78bfa]", + polkadot: + "before:bg-gradient-to-r before:from-[#e6007a] before:to-[#ff4081]", + }; + + return ( + +
+
+ {icon} +
+

{title}

+
+

{description}

+
+ ); +} + +// Ecosystem Card - With specific glow colors for each ecosystem +function EcosystemCard({ + href, + icon, + title, + description, + glowColor = "evm", + className, +}: Omit & { glowColor?: string }) { + const glowClasses = { + evm: "before:bg-gradient-to-r before:from-[#627eea] before:to-[#4945ff]", + starknet: + "before:bg-gradient-to-r before:from-[#EC796B] before:to-[#EC796B]", + rust: "before:bg-gradient-to-r before:from-[#12AAFF] before:to-[#9DCCED]", + zk: "before:bg-gradient-to-r before:from-[#10b981] before:to-[#34d399]", + stellar: + "before:bg-gradient-to-r before:from-[#FDDA33] before:to-[#F9DF74]", + midnight: + "before:bg-gradient-to-r before:from-[#2600FE] before:to-[#2600FE]", + polkadot: + "before:bg-gradient-to-r before:from-[#e6007a] before:to-[#ff4081]", + uniswap: + "before:bg-gradient-to-r before:from-[#e6007a] before:to-[#FC75FE]", + zama: "before:bg-gradient-to-r before:from-[#FFD205] before:to-[#FFD205]", + }; + + return ( + +
+
+ {icon} +
+

{title}

+
+

{description}

+
+ ); +} + +// Community Card - Similar to FeatureCard but with different icon styling +function CommunityCard({ + href, + icon, + title, + description, + className, +}: CommunityCardProps) { + return ( + +
+
+ {icon} +
+

{title}

+
+

{description}

+
+ ); +} + +// Banner Card - Special layout for Ethernaut with animated shimmer +function BannerCard({ + href, + icon, + title, + description, + className, +}: BannerCardProps) { + return ( + +
+ {icon} +
+
+

{title}

+

{description}

+
+
+
+ ); +} + +export { + HeroCard, + FeatureCard, + EcosystemCard, + CommunityCard, + BannerCard, + type GlowColor, +}; From 2b406908614e7ff87e92a40ec9ba0b58fae5de61 Mon Sep 17 00:00:00 2001 From: Steve Date: Fri, 5 Sep 2025 16:34:53 -0400 Subject: [PATCH 06/10] chore: updated ecosystem icons and logo --- src/app/layout.config.tsx | 26 +++---- src/app/page.tsx | 12 +-- src/components/icons/arbitrum-icon.tsx | 98 +++++++++++++++++------- src/components/icons/ethereum-icon.tsx | 76 +++++++++++++++---- src/components/icons/polkadot-icon.tsx | 56 ++++++++++---- src/components/icons/starknet-icon.tsx | 101 ++++++++++++++++++++----- src/components/icons/uniswap-icon.tsx | 90 ++++++++++++++-------- src/components/icons/zama-icon.tsx | 57 +++++++++----- 8 files changed, 371 insertions(+), 145 deletions(-) diff --git a/src/app/layout.config.tsx b/src/app/layout.config.tsx index dd2ff04f..1bfc8c8c 100644 --- a/src/app/layout.config.tsx +++ b/src/app/layout.config.tsx @@ -23,58 +23,58 @@ export const baseOptions: BaseLayoutProps = { OpenZeppelin Logo } + icon={} title="Ethereum & EVM" description="Solidity smart contracts for Ethereum and EVM-compatible chains" glowColor="evm" @@ -157,7 +157,7 @@ export default function HomePage() { } + icon={} title="Starknet" description="Essential contracts library written in Cairo for Starknet" glowColor="starknet" @@ -165,7 +165,7 @@ export default function HomePage() { } + icon={} title="Arbitrum Stylus" description="Essential contracts library for Arbitrum Stylus written in Rust" glowColor="rust" @@ -173,7 +173,7 @@ export default function HomePage() { } + icon={} title="Uniswap Hooks" description="Advanced Uniswap V4 hooks in Solidity" glowColor="uniswap" @@ -197,7 +197,7 @@ export default function HomePage() { } + icon={} title="Polkadot" description="ink! smart contracts for Polkadot and Substrate chains" glowColor="polkadot" @@ -205,7 +205,7 @@ export default function HomePage() { } + icon={} title="Zama FHEVM" description="Fully homomorphic encryption contracts for confidential smart contracts" glowColor="zama" diff --git a/src/components/icons/arbitrum-icon.tsx b/src/components/icons/arbitrum-icon.tsx index 73825f93..a1db5fe9 100644 --- a/src/components/icons/arbitrum-icon.tsx +++ b/src/components/icons/arbitrum-icon.tsx @@ -1,29 +1,71 @@ -export function ArbitrumIcon({ className }: { className: string }) { - return ( - - Arbitrum Icon - - - - - - ); +export function ArbitrumIcon({ + className, + color, +}: { + className: string; + color?: boolean; +}) { + if (color) { + return ( + + Arbitrum Icon + + + + + + + + + ); + } else { + return ( + + Arbitrum Icon + + + + + + ); + } } diff --git a/src/components/icons/ethereum-icon.tsx b/src/components/icons/ethereum-icon.tsx index b1ac1124..fc4a9e3c 100644 --- a/src/components/icons/ethereum-icon.tsx +++ b/src/components/icons/ethereum-icon.tsx @@ -1,17 +1,61 @@ -export function EthereumIcon({ className }: { className: string }) { - return ( - - Ethereum Icon - - - ); +export function EthereumIcon({ + className, + color, +}: { + className: string; + color?: boolean; +}) { + if (color) { + return ( + + Ethereum Icon + + + + + + + + ); + } else { + return ( + + Ethereum Icon + + + ); + } } diff --git a/src/components/icons/polkadot-icon.tsx b/src/components/icons/polkadot-icon.tsx index 55d2edc3..d3b7a52f 100644 --- a/src/components/icons/polkadot-icon.tsx +++ b/src/components/icons/polkadot-icon.tsx @@ -1,17 +1,41 @@ -export function PolkadotIcon({ className }: { className: string }) { - return ( - - Polkadot - - - ); +export function PolkadotIcon({ + className, + color, +}: { + className: string; + color?: boolean; +}) { + if (color) { + return ( + + Polkadot + + + ); + } else { + return ( + + Polkadot + + + ); + } } diff --git a/src/components/icons/starknet-icon.tsx b/src/components/icons/starknet-icon.tsx index 25edbcde..eab460a6 100644 --- a/src/components/icons/starknet-icon.tsx +++ b/src/components/icons/starknet-icon.tsx @@ -1,19 +1,84 @@ -export function StarknetIcon({ className }: { className: string }) { - return ( - - Starknet Icon - - - ); +export function StarknetIcon({ + className, + color, +}: { + className: string; + color?: boolean; +}) { + if (color) { + return ( + + Starknet Icon + + + + + + + + + + + + + + + ); + } else { + return ( + + Starknet Icon + + + ); + } } diff --git a/src/components/icons/uniswap-icon.tsx b/src/components/icons/uniswap-icon.tsx index f6cff05e..1ad19353 100644 --- a/src/components/icons/uniswap-icon.tsx +++ b/src/components/icons/uniswap-icon.tsx @@ -1,31 +1,61 @@ -export function UniswapIcon({ className }: { className: string }) { - return ( - - Uniswap Icon - - - - - - ); +export function UniswapIcon({ + className, + color, +}: { + className: string; + color?: boolean; +}) { + if (color) { + return ( + + Uniswap Icon + + + + + + + + ); + } else { + return ( + + Uniswap Icon + + + + + + ); + } } diff --git a/src/components/icons/zama-icon.tsx b/src/components/icons/zama-icon.tsx index 7ab176cc..457c2913 100644 --- a/src/components/icons/zama-icon.tsx +++ b/src/components/icons/zama-icon.tsx @@ -1,19 +1,40 @@ -export function ZamaIcon({ className }: { className: string }) { - return ( - - Zama Icon - - - - - ); +export function ZamaIcon({ + className, + color, +}: { + className: string; + color?: boolean; +}) { + if (color) { + return ( + + Zama Icon + + + + + + ); + } else { + return ( + + Zama Icon + + + + + ); + } } From be9bec629584747122e145898e8d63ada1a8c991 Mon Sep 17 00:00:00 2001 From: Steve Date: Sat, 6 Sep 2025 19:45:39 -0400 Subject: [PATCH 07/10] chore: updated icons to openzeppelin standard issue --- src/app/layout.config.tsx | 4 +- src/app/page.tsx | 37 ++++++++----- src/components/icons/annotation-dots-icon.tsx | 42 +++++++++++++++ .../icons/contracts-library-alt-icon.tsx | 46 ++++++++++++++++ .../icons/contracts-library-icon.tsx | 46 ++++++++++++++++ src/components/icons/contracts-mcp-icon.tsx | 37 +++++++++++++ .../icons/contracts-upgrades-icon.tsx | 53 +++++++++++++++++++ .../icons/contracts-wizard-icon.tsx | 35 ++++++++++++ src/components/icons/ethernaut-icon.tsx | 20 +++++++ src/components/icons/home-icon.tsx | 28 ++++++++++ src/components/icons/index.ts | 10 ++++ src/components/icons/monitor-icon.tsx | 28 ++++++++++ src/components/icons/relayers-icon.tsx | 41 ++++++++++++++ .../icons/transaction-proposal-icon.tsx | 32 +++++++++++ 14 files changed, 443 insertions(+), 16 deletions(-) create mode 100644 src/components/icons/annotation-dots-icon.tsx create mode 100644 src/components/icons/contracts-library-alt-icon.tsx create mode 100644 src/components/icons/contracts-library-icon.tsx create mode 100644 src/components/icons/contracts-mcp-icon.tsx create mode 100644 src/components/icons/contracts-upgrades-icon.tsx create mode 100644 src/components/icons/contracts-wizard-icon.tsx create mode 100644 src/components/icons/ethernaut-icon.tsx create mode 100644 src/components/icons/home-icon.tsx create mode 100644 src/components/icons/monitor-icon.tsx create mode 100644 src/components/icons/relayers-icon.tsx create mode 100644 src/components/icons/transaction-proposal-icon.tsx diff --git a/src/app/layout.config.tsx b/src/app/layout.config.tsx index 1bfc8c8c..16a69a2a 100644 --- a/src/app/layout.config.tsx +++ b/src/app/layout.config.tsx @@ -1,5 +1,5 @@ import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared"; -import { GlobeIcon, HomeIcon, MessagesSquareIcon } from "lucide-react"; +import { GlobeIcon, HomeIcon, MessageSquareMoreIcon } from "lucide-react"; /** * Shared layout configurations @@ -104,7 +104,7 @@ export const baseOptions: BaseLayoutProps = { { text: "Forum", url: "https://forum.openzeppelin.com", - icon: , + icon: , }, { text: "Website", diff --git a/src/app/page.tsx b/src/app/page.tsx index 6c0594ad..22119e2c 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -21,6 +21,15 @@ import { StellarIcon, UniswapIcon, ZamaIcon, + ContractsLibraryIcon, + ContractsMcpIcon, + ContractsUpgradesIcon, + ContractsWizardIcon, + EthernautIcon, + MonitorIcon, + RelayersIcon, + TransactionProposalIcon, + AnnotationDotsIcon, } from "@/components/icons"; import { HeroCard, @@ -54,7 +63,7 @@ export default function HomePage() { {/* Primary Hero: OpenZeppelin Contracts */} } + icon={} title="OpenZeppelin Solidity Contracts" description="The world's most popular library of Solidity contracts for Ethereum and EVM blockchains. Battle-tested, community-reviewed, and trusted by thousands of projects worldwide." /> @@ -63,21 +72,21 @@ export default function HomePage() {
} + icon={} title="Upgrades Plugins" description="Deploy and manage upgradeable contracts with built-in safety checks and best practices" /> } + icon={} title="Contracts Wizard" description="Interactive smart contract generator with security best practices built-in" /> } + icon={} title="Contracts MCP" description="AI-powered assistant for smart contract development and security analysis" /> @@ -98,7 +107,7 @@ export default function HomePage() {
} + icon={} title="Relayer" description="Enable gasless transactions and automate smart contract operations. Build better user experiences with meta-transactions and scheduled executions." glowColor="tools" @@ -106,7 +115,7 @@ export default function HomePage() { } + icon={} title="Monitor" description="Real-time monitoring and alerting for your smart contracts. Get notified about important events, transactions, and state changes across multiple chains." glowColor="tools" @@ -117,7 +126,7 @@ export default function HomePage() {
} + icon={} title="UI Builder" description="Create user interfaces for deployed contracts" /> @@ -149,7 +158,7 @@ export default function HomePage() {
} + icon={} title="Ethereum & EVM" description="Solidity smart contracts for Ethereum and EVM-compatible chains" glowColor="evm" @@ -157,7 +166,7 @@ export default function HomePage() { } + icon={} title="Starknet" description="Essential contracts library written in Cairo for Starknet" glowColor="starknet" @@ -165,7 +174,7 @@ export default function HomePage() { } + icon={} title="Arbitrum Stylus" description="Essential contracts library for Arbitrum Stylus written in Rust" glowColor="rust" @@ -173,7 +182,7 @@ export default function HomePage() { } + icon={} title="Uniswap Hooks" description="Advanced Uniswap V4 hooks in Solidity" glowColor="uniswap" @@ -197,7 +206,7 @@ export default function HomePage() { } + icon={} title="Polkadot" description="ink! smart contracts for Polkadot and Substrate chains" glowColor="polkadot" @@ -225,7 +234,7 @@ export default function HomePage() { {/* Ethernaut CTF as standalone */} } + icon={} title="Ethernaut CTF" description="Learn smart contract security by hacking! A Web3/Solidity based capture-the-flag game where each level is a smart contract that needs to be 'hacked'. Perfect for learning vulnerabilities and security best practices through hands-on challenges." badge="Interactive Learning" @@ -246,7 +255,7 @@ export default function HomePage() {
} + icon={} title="Forum" description="Deep technical discussions, architectural questions, and detailed support. Best place for in-depth conversations about smart contract development, security patterns, and implementation details." /> diff --git a/src/components/icons/annotation-dots-icon.tsx b/src/components/icons/annotation-dots-icon.tsx new file mode 100644 index 00000000..a35d5024 --- /dev/null +++ b/src/components/icons/annotation-dots-icon.tsx @@ -0,0 +1,42 @@ +export function AnnotationDotsIcon({ className }: { className: string }) { + return ( + + Annotation Dots Icon + + + + + + ); +} diff --git a/src/components/icons/contracts-library-alt-icon.tsx b/src/components/icons/contracts-library-alt-icon.tsx new file mode 100644 index 00000000..15f47460 --- /dev/null +++ b/src/components/icons/contracts-library-alt-icon.tsx @@ -0,0 +1,46 @@ +export function ContractsLibraryAltIcon({ className }: { className: string }) { + return ( + + Contracts Library Alt Icon + + + + + + ); +} diff --git a/src/components/icons/contracts-library-icon.tsx b/src/components/icons/contracts-library-icon.tsx new file mode 100644 index 00000000..561c850e --- /dev/null +++ b/src/components/icons/contracts-library-icon.tsx @@ -0,0 +1,46 @@ +export function ContractsLibraryIcon({ className }: { className: string }) { + return ( + + Contracts Library Icon + + + + + + ); +} diff --git a/src/components/icons/contracts-mcp-icon.tsx b/src/components/icons/contracts-mcp-icon.tsx new file mode 100644 index 00000000..d5ebad32 --- /dev/null +++ b/src/components/icons/contracts-mcp-icon.tsx @@ -0,0 +1,37 @@ +export function ContractsMcpIcon({ className }: { className: string }) { + return ( + + Contracts MCP Icon + + + + + ); +} diff --git a/src/components/icons/contracts-upgrades-icon.tsx b/src/components/icons/contracts-upgrades-icon.tsx new file mode 100644 index 00000000..801514b8 --- /dev/null +++ b/src/components/icons/contracts-upgrades-icon.tsx @@ -0,0 +1,53 @@ +export function ContractsUpgradesIcon({ className }: { className: string }) { + return ( + + Contracts Upgrades Icon + + + + + + + ); +} diff --git a/src/components/icons/contracts-wizard-icon.tsx b/src/components/icons/contracts-wizard-icon.tsx new file mode 100644 index 00000000..0bf1809a --- /dev/null +++ b/src/components/icons/contracts-wizard-icon.tsx @@ -0,0 +1,35 @@ +export function ContractsWizardIcon({ className }: { className: string }) { + return ( + + Contracts Wizard Icon + + + + + ); +} diff --git a/src/components/icons/ethernaut-icon.tsx b/src/components/icons/ethernaut-icon.tsx new file mode 100644 index 00000000..17fd7894 --- /dev/null +++ b/src/components/icons/ethernaut-icon.tsx @@ -0,0 +1,20 @@ +export function EthernautIcon({ className }: { className: string }) { + return ( + + Ethernaut Icon + + + ); +} diff --git a/src/components/icons/home-icon.tsx b/src/components/icons/home-icon.tsx new file mode 100644 index 00000000..36fc5e53 --- /dev/null +++ b/src/components/icons/home-icon.tsx @@ -0,0 +1,28 @@ +export function HomeIcon({ className }: { className: string }) { + return ( + + Home Icon + + + + ); +} diff --git a/src/components/icons/index.ts b/src/components/icons/index.ts index 1ed8bf6c..9bc84b9c 100644 --- a/src/components/icons/index.ts +++ b/src/components/icons/index.ts @@ -1,8 +1,18 @@ +export { AnnotationDotsIcon } from "./annotation-dots-icon"; export { ArbitrumIcon } from "./arbitrum-icon"; +export { ContractsLibraryIcon } from "./contracts-library-icon"; +export { ContractsMcpIcon } from "./contracts-mcp-icon"; +export { ContractsUpgradesIcon } from "./contracts-upgrades-icon"; +export { ContractsWizardIcon } from "./contracts-wizard-icon"; +export { EthernautIcon } from "./ethernaut-icon"; export { EthereumIcon } from "./ethereum-icon"; +export { HomeIcon } from "./home-icon"; export { MidnightIcon } from "./midnight-icon"; +export { MonitorIcon } from "./monitor-icon"; export { PolkadotIcon } from "./polkadot-icon"; +export { RelayersIcon } from "./relayers-icon"; export { StarknetIcon } from "./starknet-icon"; export { StellarIcon } from "./stellar-icon"; +export { TransactionProposalIcon } from "./transaction-proposal-icon"; export { UniswapIcon } from "./uniswap-icon"; export { ZamaIcon } from "./zama-icon"; diff --git a/src/components/icons/monitor-icon.tsx b/src/components/icons/monitor-icon.tsx new file mode 100644 index 00000000..205015ff --- /dev/null +++ b/src/components/icons/monitor-icon.tsx @@ -0,0 +1,28 @@ +export function MonitorIcon({ className }: { className: string }) { + return ( + + Monitor Icon + + + + ); +} diff --git a/src/components/icons/relayers-icon.tsx b/src/components/icons/relayers-icon.tsx new file mode 100644 index 00000000..1056e2cb --- /dev/null +++ b/src/components/icons/relayers-icon.tsx @@ -0,0 +1,41 @@ +export function RelayersIcon({ className }: { className: string }) { + return ( + + Relayers Icon + + + + + + ); +} diff --git a/src/components/icons/transaction-proposal-icon.tsx b/src/components/icons/transaction-proposal-icon.tsx new file mode 100644 index 00000000..e61ef4bf --- /dev/null +++ b/src/components/icons/transaction-proposal-icon.tsx @@ -0,0 +1,32 @@ +export function TransactionProposalIcon({ className }: { className: string }) { + return ( + + Transaction Proposal Icon + + + + + ); +} From 922249873d3cb1da9a65be8cb59e9d4c118ae57e Mon Sep 17 00:00:00 2001 From: Steve Date: Sat, 6 Sep 2025 19:53:40 -0400 Subject: [PATCH 08/10] chore: updated icon imports --- src/app/page.tsx | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index 22119e2c..95979e02 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,17 +1,5 @@ import { HomeLayout } from "fumadocs-ui/layouts/home"; -import { - ActivityIcon, - ArrowUpIcon, - GamepadIcon, - LibraryIcon, - MessageCircleIcon, - SatelliteDishIcon, - SendIcon, - ShieldIcon, - WallpaperIcon, - WandSparklesIcon, - WrenchIcon, -} from "lucide-react"; +import { ShieldIcon, WrenchIcon, SendIcon } from "lucide-react"; import { ArbitrumIcon, EthereumIcon, From afa0658767e3ca05cf3270587f7252198fbca0ae Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 8 Sep 2025 09:51:53 -0400 Subject: [PATCH 09/10] feat: added footer --- src/app/page.tsx | 2 + src/components/footer.tsx | 315 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 317 insertions(+) create mode 100644 src/components/footer.tsx diff --git a/src/app/page.tsx b/src/app/page.tsx index 95979e02..4a995e04 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -27,6 +27,7 @@ import { BannerCard, } from "@/components/home-cards"; import { baseOptions } from "./layout.config"; +import { Footer } from "@/components/footer"; export default function HomePage() { return ( @@ -257,6 +258,7 @@ export default function HomePage() {
+