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
464 changes: 464 additions & 0 deletions app/components/homepage.tsx

Large diffs are not rendered by default.

42 changes: 27 additions & 15 deletions app/components/viem-account-demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,13 @@ import {
DialogTrigger,
} from "@/components/ui/dialog";
import { PaymentWidgetWrapper } from "./payment-widget-wrapper";
import { useState } from "react";
import { useState, useMemo } from "react";
import { Wallet, LogOut } from "lucide-react";

interface ViemAccountDemoProps {
recipientWallet: string;
}

const config = createConfig({
chains: [mainnet, sepolia],
connectors: [injected(), metaMask()],
transports: {
[mainnet.id]: http(),
[sepolia.id]: http(),
},
});

// Create a query client
const queryClient = new QueryClient();

function ViemAccountDemoInner({ recipientWallet }: ViemAccountDemoProps) {
const { address, isConnected } = useAccount();
const { connectors, connect, isPending } = useConnect();
Expand Down Expand Up @@ -138,11 +126,35 @@ function ViemAccountDemoInner({ recipientWallet }: ViemAccountDemoProps) {
);
}

export function ViemAccountDemo(props: ViemAccountDemoProps) {
function createDemoWagmiConfig() {
return createConfig({
chains: [mainnet, sepolia],
connectors: [injected(), metaMask()],
transports: {
[mainnet.id]: http(),
[sepolia.id]: http(),
},
});
}

export function ViemAccountDemo({ recipientWallet }: ViemAccountDemoProps) {
const config = useMemo(() => createDemoWagmiConfig(), []);
const queryClient = useMemo(
() =>
new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 5, // 5 minutes
},
},
}),
[],
);

return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<ViemAccountDemoInner {...props} />
<ViemAccountDemoInner recipientWallet={recipientWallet} />
</QueryClientProvider>
</WagmiProvider>
);
Expand Down
43 changes: 18 additions & 25 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,25 @@
import { PaymentWidgetWrapper } from "./components/payment-widget-wrapper";
import { ViemAccountDemo } from "./components/viem-account-demo";
import { promises as fs } from "fs";
import path from "path";
import { HomePage } from "./components/homepage";

export default function Home() {
const recipientWallet = process.env.RECIPIENT_WALLET || "";
export default async function Home() {
const recipientWallet =
process.env.RECIPIENT_WALLET ||
"0x0000000000000000000000000000000000000000";

// Load README content
const readmePath = path.join(
process.cwd(),
"registry/default/payment-widget/README.md",
);
const readmeContent = await fs.readFile(readmePath, "utf8");

return (
<main className="container mx-auto py-8 px-4 space-y-8">
<h1 className="text-2xl font-bold mb-6">RequestNetwork UI Registry</h1>

<div className="space-y-8">
<div>
<h2 className="text-lg font-semibold mb-4">
Payment Widget Preview:
</h2>
<PaymentWidgetWrapper recipientWallet={recipientWallet} />
</div>

<div>
<ViemAccountDemo recipientWallet={recipientWallet} />
</div>
</div>

<div className="bg-primary p-4 rounded">
<h3 className="font-semibold mb-2">Install this component:</h3>
<code className="text-sm">
npx shadcn add @requestnetwork/payment-widget
</code>
</div>
<HomePage
recipientWallet={recipientWallet}
readmeContent={readmeContent}
/>
</main>
);
}
163 changes: 163 additions & 0 deletions components/markdown-renderer/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
"use client";
import ReactMarkdown from "react-markdown";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { darcula } from "react-syntax-highlighter/dist/esm/styles/prism";

export function MarkdownRenderer({ markdown }: { markdown: string }) {
return (
<div className="prose prose-neutral dark:prose-invert max-w-none">
<ReactMarkdown
components={{
// Headings
h1: ({ children }) => (
<h1 className="text-3xl font-bold mb-6 text-foreground border-b border-border pb-2">
{children}
</h1>
),
h2: ({ children }) => (
<h2 className="text-2xl font-semibold mb-4 mt-8 text-foreground">
{children}
</h2>
),
h3: ({ children }) => (
<h3 className="text-xl font-semibold mb-3 mt-6 text-foreground">
{children}
</h3>
),
h4: ({ children }) => (
<h4 className="text-lg font-semibold mb-2 mt-4 text-foreground">
{children}
</h4>
),
h5: ({ children }) => (
<h5 className="text-base font-semibold mb-2 mt-4 text-foreground">
{children}
</h5>
),
h6: ({ children }) => (
<h6 className="text-sm font-semibold mb-2 mt-4 text-foreground">
{children}
</h6>
),

// Paragraphs
p: ({ children }) => (
<p className="mb-4 text-muted-foreground leading-relaxed">
{children}
</p>
),

// Lists
ul: ({ children }) => (
<ul className="list-disc list-inside mb-4 space-y-1 text-muted-foreground ml-4">
{children}
</ul>
),
ol: ({ children }) => (
<ol className="list-decimal list-inside mb-4 space-y-1 text-muted-foreground ml-4">
{children}
</ol>
),
li: ({ children }) => <li className="mb-1">{children}</li>,

// Links
a: ({ href, children }) => (
<a
href={href}
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline"
>
{children}
</a>
),

// Emphasis
strong: ({ children }) => (
<strong className="font-semibold text-foreground">
{children}
</strong>
),
em: ({ children }) => <em className="italic">{children}</em>,

// Blockquotes
blockquote: ({ children }) => (
<blockquote className="border-l-4 border-primary pl-4 italic text-muted-foreground my-4 bg-muted/30 py-2">
{children}
</blockquote>
),

// Tables
table: ({ children }) => (
<div className="overflow-x-auto mb-4">
<table className="min-w-full border border-border rounded-lg">
{children}
</table>
</div>
),
thead: ({ children }) => (
<thead className="bg-muted">{children}</thead>
),
tbody: ({ children }) => (
<tbody className="divide-y divide-border">{children}</tbody>
),
tr: ({ children }) => (
<tr className="hover:bg-muted/50">{children}</tr>
),
th: ({ children }) => (
<th className="px-4 py-2 text-left font-semibold text-foreground">
{children}
</th>
),
td: ({ children }) => (
<td className="px-4 py-2 text-muted-foreground">{children}</td>
),

// Horizontal rule
hr: () => <hr className="my-8 border-border" />,

// Code (inline and blocks)
code(props) {
const { children, className, node, ...rest } = props;
const match = /language-(\w+)/.exec(className || "");

return match ? (
<div className="my-4">
<SyntaxHighlighter
/* @ts-expect-error - SyntaxHighlighter types are outdated and cause style prop conflicts */
style={darcula}
language={match[1]}
PreTag="div"
customStyle={{
margin: 0,
borderRadius: "0.5rem",
fontSize: "0.875rem",
}}
{...rest}
>
{String(children).replace(/\n$/, "")}
</SyntaxHighlighter>
</div>
) : (
<code
className="bg-muted px-1.5 py-0.5 rounded text-sm font-mono text-foreground"
{...rest}
>
{children}
</code>
);
},

// Pre (for code blocks without language)
pre: ({ children }) => (
<pre className="bg-muted p-4 rounded-lg overflow-x-auto mb-4 text-sm">
{children}
</pre>
),
}}
>
{markdown}
</ReactMarkdown>
</div>
);
}
79 changes: 79 additions & 0 deletions components/ui/card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import * as React from "react"

import { cn } from "@/lib/utils"

const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"rounded-lg border bg-card text-card-foreground shadow-sm",
className
)}
{...props}
/>
))
Card.displayName = "Card"

const CardHeader = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex flex-col space-y-1.5 p-6", className)}
{...props}
/>
))
CardHeader.displayName = "CardHeader"

const CardTitle = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"text-2xl font-semibold leading-none tracking-tight",
className
)}
{...props}
/>
))
CardTitle.displayName = "CardTitle"

const CardDescription = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
CardDescription.displayName = "CardDescription"

const CardContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
))
CardContent.displayName = "CardContent"

const CardFooter = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex items-center p-6 pt-0", className)}
{...props}
/>
))
CardFooter.displayName = "CardFooter"

export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
11 changes: 11 additions & 0 deletions components/ui/collapsible.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"use client"

import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"

const Collapsible = CollapsiblePrimitive.Root

const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger

const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent

export { Collapsible, CollapsibleTrigger, CollapsibleContent }
Loading