diff --git a/.eslintrc.json b/.eslintrc.json index 2b6e7dfa818..190ff1656e4 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -90,6 +90,7 @@ "coverage/", "storybook-static/", "**/*.d.ts", - "src/intl/" + "src/intl/", + "public/code-examples/" ] } diff --git a/app/[locale]/page.tsx b/app/[locale]/page.tsx index 606fe0ca3fc..9e36af110ef 100644 --- a/app/[locale]/page.tsx +++ b/app/[locale]/page.tsx @@ -67,7 +67,6 @@ import { getMetadata } from "@/lib/utils/metadata" import { polishRSSList } from "@/lib/utils/rss" import events from "@/data/community-events.json" -import CreateWalletContent from "@/data/CreateWallet" import { ATTESTANT_BLOG, @@ -84,9 +83,6 @@ import { import TenYearHomeBanner from "./10years/_components/TenYearHomeBanner" import { getActivity } from "./utils" -import SimpleDomainRegistryContent from "!!raw-loader!@/data/SimpleDomainRegistry.sol" -import SimpleTokenContent from "!!raw-loader!@/data/SimpleToken.sol" -import SimpleWalletContent from "!!raw-loader!@/data/SimpleWallet.sol" import { routing } from "@/i18n/routing" import { fetchCommunityEvents } from "@/lib/api/calendarEvents" import { fetchEthPrice } from "@/lib/api/fetchEthPrice" @@ -341,28 +337,28 @@ const Page = async ({ params }: { params: Promise<{ locale: Lang }> }) => { title: t("page-index-developers-code-example-title-0"), description: t("page-index-developers-code-example-description-0"), codeLanguage: "language-solidity", - code: SimpleWalletContent, + codeUrl: "/code-examples/SimpleWallet.sol", eventName: "bank", }, { title: t("page-index-developers-code-example-title-1"), description: t("page-index-developers-code-example-description-1"), codeLanguage: "language-solidity", - code: SimpleTokenContent, + codeUrl: "/code-examples/SimpleToken.sol", eventName: "token", }, { title: t("page-index-developers-code-example-title-2"), description: t("page-index-developers-code-example-description-2"), codeLanguage: "language-javascript", - code: CreateWalletContent, + codeUrl: "/code-examples/CreateWallet.js", eventName: "wallet", }, { title: t("page-index-developers-code-example-title-3"), description: t("page-index-developers-code-example-description-3"), codeLanguage: "language-solidity", - code: SimpleDomainRegistryContent, + codeUrl: "/code-examples/SimpleDomainRegistry.sol", eventName: "dns", }, ] diff --git a/src/data/CreateWallet.ts b/public/code-examples/CreateWallet.js similarity index 94% rename from src/data/CreateWallet.ts rename to public/code-examples/CreateWallet.js index 4931a7c7af6..6ed5d772492 100644 --- a/src/data/CreateWallet.ts +++ b/public/code-examples/CreateWallet.js @@ -1,4 +1,4 @@ -const createWallet = `const ethers = require("ethers") +const ethers = require("ethers") // Create a wallet instance from a mnemonic... const mnemonic = @@ -46,6 +46,3 @@ wallet.sendTransaction(tx) // https://github.com/ethers-io/ethers.js/blob/master/docs/v5/api/signer/README.md#methods // Content is licensed under the Creative Commons License: // https://choosealicense.com/licenses/cc-by-4.0/ -` - -export default createWallet diff --git a/src/data/SimpleDomainRegistry.sol b/public/code-examples/SimpleDomainRegistry.sol similarity index 100% rename from src/data/SimpleDomainRegistry.sol rename to public/code-examples/SimpleDomainRegistry.sol diff --git a/src/data/SimpleToken.sol b/public/code-examples/SimpleToken.sol similarity index 100% rename from src/data/SimpleToken.sol rename to public/code-examples/SimpleToken.sol diff --git a/src/data/SimpleWallet.sol b/public/code-examples/SimpleWallet.sol similarity index 100% rename from src/data/SimpleWallet.sol rename to public/code-examples/SimpleWallet.sol diff --git a/src/components/CodeModal.tsx b/src/components/CodeModal.tsx index 938008a14bc..2bbd1116750 100644 --- a/src/components/CodeModal.tsx +++ b/src/components/CodeModal.tsx @@ -23,7 +23,7 @@ type CodeModalProps = { const CodeModal = ({ children, isOpen, setIsOpen, title }: CodeModalProps) => { const { t } = useTranslation() const codeSnippet = (Children.toArray(children)[0] as ReactElement).props - .children.props.children + .children const { onCopy, hasCopied } = useClipboard() diff --git a/src/components/Homepage/CodeExamples.tsx b/src/components/Homepage/CodeExamples.tsx index 36cab10893f..bd932ce8651 100644 --- a/src/components/Homepage/CodeExamples.tsx +++ b/src/components/Homepage/CodeExamples.tsx @@ -1,6 +1,6 @@ "use client" -import { Suspense, useState } from "react" +import { useCallback, useEffect, useState } from "react" import { Clipboard, ClipboardCheck } from "lucide-react" import { useLocale } from "next-intl" @@ -29,17 +29,64 @@ type CodeExamplesProps = { eventCategory: string } +const AccordionCodeBlock = ({ + code, + codeLanguage, +}: { + code: string + codeLanguage: string +}) => ( + <> + + {code} + + + {(hasCopied) => (hasCopied ? : )} + + > +) + const CodeExamples = ({ title, codeExamples }: CodeExamplesProps) => { const locale = useLocale() const [isModalOpen, setModalOpen] = useState(false) const [activeCode, setActiveCode] = useState(0) + const [fetchedCodes, setFetchedCodes] = useState<{ [key: number]: string }>( + {} + ) const eventCategory = `Homepage - ${locale}` - const toggleCodeExample = (id: number): void => { - setActiveCode(id) - setModalOpen(true) + const getCode = useCallback( + (idx: number) => { + const example = codeExamples[idx] + if (!fetchedCodes[idx]) { + fetch(example.codeUrl) + .then((res) => res.text()) + .then((text) => setFetchedCodes((prev) => ({ ...prev, [idx]: text }))) + } + }, + [codeExamples, fetchedCodes] + ) + + // For modal: fetch code when opened if needed + useEffect(() => { + if (isModalOpen) { + getCode(activeCode) + } + }, [isModalOpen, activeCode, getCode]) + + // For accordion: fetch code when expanded if needed + const handleAccordionOpen = (idx: number) => { + getCode(idx) } return ( @@ -54,7 +101,8 @@ const CodeExamples = ({ title, codeExamples }: CodeExamplesProps) => { isModalOpen && idx === activeCode && "bg-background-highlight" )} onClick={() => { - toggleCodeExample(idx) + setActiveCode(idx) + setModalOpen(true) trackCustomEvent({ eventCategory, eventAction: "Code Examples", @@ -68,9 +116,12 @@ const CodeExamples = ({ title, codeExamples }: CodeExamplesProps) => { ))} {/* Mobile */} - {codeExamples.map(({ title, description, code, codeLanguage }) => ( + {codeExamples.map(({ title, description, codeLanguage }, idx) => ( - + handleAccordionOpen(idx)} + > {title} @@ -81,26 +132,16 @@ const CodeExamples = ({ title, codeExamples }: CodeExamplesProps) => { - }> - - + {!fetchedCodes[idx] ? ( + + ) : ( + - {code} - - - {(hasCopied) => - hasCopied ? : - } - - - + /> + )} + ))} @@ -112,16 +153,18 @@ const CodeExamples = ({ title, codeExamples }: CodeExamplesProps) => { setIsOpen={setModalOpen} title={codeExamples[activeCode].title} > - }> + {!fetchedCodes[activeCode] ? ( + + ) : ( - {codeExamples[activeCode].code} + {fetchedCodes[activeCode]} - + )} )} diff --git a/src/lib/interfaces.ts b/src/lib/interfaces.ts index 092a7b62647..2577e220d03 100644 --- a/src/lib/interfaces.ts +++ b/src/lib/interfaces.ts @@ -174,6 +174,6 @@ export interface CodeExample { alt?: string id?: number codeLanguage: string - code: string + codeUrl: string eventName: string }
{title} @@ -81,26 +132,16 @@ const CodeExamples = ({ title, codeExamples }: CodeExamplesProps) => {