Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
"coverage/",
"storybook-static/",
"**/*.d.ts",
"src/intl/"
"src/intl/",
"public/code-examples/"
]
}
12 changes: 4 additions & 8 deletions app/[locale]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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"
Expand Down Expand Up @@ -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",
},
]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const createWallet = `const ethers = require("ethers")
const ethers = require("ethers")

// Create a wallet instance from a mnemonic...
const mnemonic =
Expand Down Expand Up @@ -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
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion src/components/CodeModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
101 changes: 72 additions & 29 deletions src/components/Homepage/CodeExamples.tsx
Original file line number Diff line number Diff line change
@@ -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"

Expand Down Expand Up @@ -29,17 +29,64 @@ type CodeExamplesProps = {
eventCategory: string
}

const AccordionCodeBlock = ({
code,
codeLanguage,
}: {
code: string
codeLanguage: string
}) => (
<>
<Codeblock
codeLanguage={codeLanguage}
allowCollapse={false}
className="[&>div]:-m-//2 [&>div]:rounded-none [&_*]:!text-xs [&_pre]:p-4"
fromHomepage
>
{code}
</Codeblock>
<CopyToClipboard
text={code ?? ""}
className="absolute end-2 top-2 rounded p-2 hover:bg-primary/10 hover:text-primary"
>
{(hasCopied) => (hasCopied ? <ClipboardCheck /> : <Clipboard />)}
</CopyToClipboard>
</>
)

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 (
Expand All @@ -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",
Expand All @@ -68,9 +116,12 @@ const CodeExamples = ({ title, codeExamples }: CodeExamplesProps) => {
))}
{/* Mobile */}
<Accordion type="single" collapsible className="md:hidden">
{codeExamples.map(({ title, description, code, codeLanguage }) => (
{codeExamples.map(({ title, description, codeLanguage }, idx) => (
<AccordionItem key={title} value={title} className="relative">
<AccordionTrigger className="flex border-t px-6 py-4 hover:bg-background-highlight">
<AccordionTrigger
className="flex border-t px-6 py-4 hover:bg-background-highlight"
onClick={() => handleAccordionOpen(idx)}
>
<div className="flex flex-col items-start gap-y-0.5">
<p className="text-start text-md font-bold text-body">
{title}
Expand All @@ -81,26 +132,16 @@ const CodeExamples = ({ title, codeExamples }: CodeExamplesProps) => {
</div>
</AccordionTrigger>
<AccordionContent className="relative border-t" dir="ltr">
<Suspense fallback={<SkeletonLines noOfLines={16} />}>
<div className="-m-2 max-h-[50vh] overflow-auto">
<Codeblock
<div className="-m-2 max-h-[50vh] overflow-auto">
{!fetchedCodes[idx] ? (
<SkeletonLines noOfLines={16} />
) : (
<AccordionCodeBlock
code={fetchedCodes[idx]}
codeLanguage={codeLanguage}
allowCollapse={false}
className="[&>div]:-m-//2 [&>div]:rounded-none [&_*]:!text-xs [&_pre]:p-4"
fromHomepage
>
{code}
</Codeblock>
<CopyToClipboard
text={code}
className="absolute end-2 top-2 rounded p-2 hover:bg-primary/10 hover:text-primary"
>
{(hasCopied) =>
hasCopied ? <ClipboardCheck /> : <Clipboard />
}
</CopyToClipboard>
</div>
</Suspense>
/>
)}
</div>
</AccordionContent>
</AccordionItem>
))}
Expand All @@ -112,16 +153,18 @@ const CodeExamples = ({ title, codeExamples }: CodeExamplesProps) => {
setIsOpen={setModalOpen}
title={codeExamples[activeCode].title}
>
<Suspense fallback={<SkeletonLines noOfLines={16} dir="ltr" />}>
{!fetchedCodes[activeCode] ? (
<SkeletonLines noOfLines={16} />
) : (
<Codeblock
codeLanguage={codeExamples[activeCode].codeLanguage}
allowCollapse={false}
className="[&_pre]:p-6"
fromHomepage
>
{codeExamples[activeCode].code}
{fetchedCodes[activeCode]}
</Codeblock>
</Suspense>
)}
</CodeModal>
)}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/lib/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,6 @@ export interface CodeExample {
alt?: string
id?: number
codeLanguage: string
code: string
codeUrl: string
eventName: string
}