Skip to content

Conversation

bassgeta
Copy link
Contributor

@bassgeta bassgeta commented Sep 18, 2025

Problem

There is no central document for integrating the payment widget.

Solution

Add it to the UI registry page.

Changes

  • Reworked the homepage to have basic code examples + functionality
  • Include installation steps on the homepage

Summary by CodeRabbit

  • New Features

    • Interactive homepage with three tabs (Examples, Installation, Documentation), live previews for widget usage (with or without a connected wallet), collapsible example panels, and per-section copy-to-clipboard feedback.
    • Reusable UI primitives for consistent cards, tabs, and collapsibles.
  • Documentation

    • In-page rendered Markdown documentation with syntax-highlighted code samples loaded into the homepage.
  • Chores

    • Added dependencies for tabs/collapsible, Markdown rendering, and code syntax highlighting.

@bassgeta bassgeta self-assigned this Sep 18, 2025
Copy link
Contributor

coderabbitai bot commented Sep 18, 2025

Walkthrough

Adds a client-side HomePage component (Examples, Installation, Documentation) with live previews, copy-to-clipboard, and Markdown docs; introduces UI primitives (Card, Tabs, Collapsible), a MarkdownRenderer, refactors ViemAccountDemo to memoize configs, updates app/page.tsx to async and load README content, and adds related dependencies.

Changes

Cohort / File(s) Summary
Homepage feature
app/components/homepage.tsx
Adds client HomePage component with Examples/Installation/Documentation tabs, collapsible example sections, live previews (PaymentWidgetWrapper / ViemAccountDemo), per-item copy feedback, env-driven API URL usage, and readmeContent prop. Exports: HomePage.
Page integration
app/page.tsx
Converts page to async, reads README at runtime into readmeContent, sets recipientWallet fallback to 0x0000000000000000000000000000000000000000, and renders <HomePage recipientWallet={recipientWallet} readmeContent={readmeContent} />.
UI primitives
components/ui/card.tsx, components/ui/tabs.tsx, components/ui/collapsible.tsx
Adds Card system (Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter), Tabs wrappers (Tabs, TabsList, TabsTrigger, TabsContent), and Collapsible re-exports (Collapsible, CollapsibleTrigger, CollapsibleContent).
Markdown renderer
components/markdown-renderer/index.tsx
Adds MarkdownRenderer component using react-markdown and react-syntax-highlighter with custom renderers and styling for headings, lists, tables, code blocks, links, and blockquotes.
Viem demo refactor
app/components/viem-account-demo.tsx
Moves Wagmi and QueryClient creation into component scope using useMemo, changes export signature to ViemAccountDemo({ recipientWallet }), and passes recipientWallet explicitly.
Dependencies
package.json
Adds runtime deps: @radix-ui/react-collapsible, @radix-ui/react-tabs, react-markdown, react-syntax-highlighter; adds devDependency @types/react-syntax-highlighter.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant Page as app/page.tsx
  participant Home as HomePage
  participant MD as MarkdownRenderer
  participant PW as PaymentWidgetWrapper
  participant VA as ViemAccountDemo
  participant CB as Clipboard API
  note right of Page: reads README file\ncomputes recipientWallet

  U->>Page: GET /
  Page->>Home: render HomePage(recipientWallet, readmeContent)
  Home->>MD: render(readmeContent) [Documentation tab]
  U->>Home: open Examples tab
  alt no wallet
    Home->>PW: render PaymentWidget (basic)
  else wallet present
    Home->>VA: render ViemAccountDemo (advanced)
  end
  U->>Home: click "Copy" code/step
  Home->>CB: navigator.clipboard.writeText(...)
  CB-->>Home: success
  Home-->>U: show "Copied!" feedback (2s)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Feat/payment widget #1 — Overlaps on UI primitives and demo components changes; likely touches the same modules.

Suggested reviewers

  • rodrigopavezi
  • aimensahnoun
  • MantisClone

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "docs: rework homepage to display integration steps" accurately and concisely summarizes the primary change in the PR—reworking the homepage to present integration steps and example documentation—making it clear to reviewers what the main intent is. It is specific, readable, and aligned with the changes described in the PR summary (homepage refactor, added integration steps and documentation rendering).
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch docs/how-to

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c6835a0 and 334a1e6.

📒 Files selected for processing (2)
  • app/components/homepage.tsx (1 hunks)
  • components/markdown-renderer/index.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • app/components/homepage.tsx
  • components/markdown-renderer/index.tsx

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
components/ui/card.tsx (1)

32-44: Use semantic elements for better a11y (h3/p instead of divs)

CardTitle/Description should be headings and paragraphs for screen readers.

Apply:

-const CardTitle = React.forwardRef<
-  HTMLDivElement,
-  React.HTMLAttributes<HTMLDivElement>
->(({ className, ...props }, ref) => (
-  <div
+const CardTitle = React.forwardRef<
+  HTMLHeadingElement,
+  React.HTMLAttributes<HTMLHeadingElement>
+>(({ className, ...props }, ref) => (
+  <h3
     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
+const CardDescription = React.forwardRef<
+  HTMLParagraphElement,
+  React.HTMLAttributes<HTMLParagraphElement>
+>(({ className, ...props }, ref) => (
+  <p
     ref={ref}
     className={cn("text-sm text-muted-foreground", className)}
     {...props}
-  />
+  />
 ))
 CardDescription.displayName = "CardDescription"

Also applies to: 47-57

app/page.tsx (1)

2-3: Remove unused imports

PaymentWidgetWrapper and ViemAccountDemo are no longer used here.

Apply:

-import { PaymentWidgetWrapper } from "./components/payment-widget-wrapper";
-import { ViemAccountDemo } from "./components/viem-account-demo";
app/components/homepage.tsx (2)

26-30: Handle clipboard errors to avoid false “Copied!” state

navigator.clipboard can fail (permissions/HTTP). Add try/catch and only set copied state on success.

Apply:

-  const copyToClipboard = (text: string, stepIndex: number) => {
-    navigator.clipboard.writeText(text);
-    setCopiedStep(stepIndex);
-    setTimeout(() => setCopiedStep(null), 2000);
-  };
+  const copyToClipboard = async (text: string, stepIndex: number) => {
+    try {
+      await navigator.clipboard.writeText(text);
+      setCopiedStep(stepIndex);
+    } catch (err) {
+      console.error("Copy failed:", err);
+      return;
+    } finally {
+      setTimeout(() => setCopiedStep(null), 2000);
+    }
+  };

336-341: Use stable keys instead of array index

Keys based on index harm list diffing. Titles are stable here.

Apply:

-              <Card
-                key={`installation-step-${
-                  // biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
-                  index
-                }`}
+              <Card
+                key={`installation-step-${step.title}`}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f5e67bf and 436b09d.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (5)
  • app/components/homepage.tsx (1 hunks)
  • app/page.tsx (1 hunks)
  • components/ui/card.tsx (1 hunks)
  • components/ui/collapsible.tsx (1 hunks)
  • package.json (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
components/ui/card.tsx (1)
lib/utils.ts (1)
  • cn (4-6)
app/page.tsx (1)
app/components/homepage.tsx (1)
  • HomePage (21-400)
app/components/homepage.tsx (2)
app/components/payment-widget-wrapper.tsx (1)
  • PaymentWidgetWrapper (11-90)
app/components/viem-account-demo.tsx (1)
  • ViemAccountDemo (141-149)
🔇 Additional comments (4)
app/components/homepage.tsx (3)

210-268: Collapsible usage looks good (post-fix)

Once the Collapsible export names are fixed, the asChild trigger pattern over CardHeader and the open state toggles look correct.

After fixing the Collapsible exports, please manually verify that expanding/collapsing works for both cards and that ARIA attributes update on the trigger.

Also applies to: 270-326


190-203: Nice landing copy and structure

Clear title/description and constrained width improve readability.


148-176: Staging registry URL in docs snippet

The components.json example points to the staging registry (app/components/homepage.tsx:173 — "@RequestNetwork": "https://ui.stage.request.network/r/{name}.json"); for external users this should reference the production registry (e.g. "https://ui.request.network/r/{name}.json"). I verified the staging site is live. (ui.stage.request.network) I could not confirm or reach a production registry at https://ui.request.network. () Confirm the correct production URL and update the snippet.

package.json (1)

15-15: Radix peer deps compatible with React 19 — no action required.
npm view shows @radix-ui/react-collapsible@^1.1.12 peerDependencies include "react" and "react-dom" ranges that include 19.0 (React 19.1.0 satisfies); npm ls shows the package isn't installed locally — run install to populate node_modules if needed.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
app/page.tsx (1)

6-9: Zero-address default acknowledged for demos

Per prior learning, keeping 0x000… as the default recipient for the showcase is acceptable to avoid real payouts. No change needed.

If you ever promote this page beyond demos, confirm RECIPIENT_WALLET is set in the environment in those deployments.

🧹 Nitpick comments (7)
components/markdown-renderer/index.tsx (2)

2-5: Enable GFM to actually render tables, strikethrough, and task lists

You provide table renderers but ReactMarkdown won’t parse tables without remark-gfm.

Apply:

 import ReactMarkdown from "react-markdown";
+import remarkGfm from "remark-gfm";
@@
-      <ReactMarkdown
+      <ReactMarkdown
+        remarkPlugins={[remarkGfm]}

Also applies to: 9-16, 90-114


63-73: Anchor hardening (nit): guard undefined href and reduce referrer leakage

Minor DX: default href to "#" to avoid invalid anchors; optionally add referrerPolicy.

Apply:

-          a: ({ href, children }) => (
+          a: ({ href, children }) => (
             <a
-              href={href}
+              href={href ?? "#"}
               target="_blank"
-              rel="noopener noreferrer"
+              rel="noopener noreferrer"
+              referrerPolicy="no-referrer"
               className="text-primary hover:underline"
             >
               {children}
             </a>
           ),
app/page.tsx (1)

10-15: Gracefully handle missing README to avoid a 500

Wrap readFile in try/catch and show a fallback so the homepage still renders if the path changes.

Apply:

-  const readmeContent = await fs.readFile(readmePath, "utf8");
+  let readmeContent = "";
+  try {
+    readmeContent = await fs.readFile(readmePath, "utf8");
+  } catch (err) {
+    readmeContent = "# Documentation\n\nREADME not found at runtime.";
+    console.warn("README load failed:", err);
+  }
app/components/viem-account-demo.tsx (1)

129-137: Connector set likely duplicates MetaMask; simplify to reduce confusion

Including both injected() and metaMask() may surface two nearly identical options. Consider one, or dedupe with a map.

Apply:

 function createDemoWagmiConfig() {
   return createConfig({
     chains: [mainnet, sepolia],
-    connectors: [injected(), metaMask()],
+    connectors: [injected({ shimDisconnect: true })],
     transports: {
       [mainnet.id]: http(),
       [sepolia.id]: http(),
     },
   });
 }
app/components/homepage.tsx (3)

27-29: Code‑split the heavy wallet demo to cut initial JS

Load ViemAccountDemo on demand with dynamic import; it pulls wagmi/react‑query.

Apply:

-import { ViemAccountDemo } from "./viem-account-demo";
+import dynamic from "next/dynamic";
+const ViemAccountDemo = dynamic(
+  () => import("./viem-account-demo").then((m) => m.ViemAccountDemo),
+  { ssr: false },
+);

Also applies to: 336-346


41-45: Clipboard API fallback (nit)

navigator.clipboard requires secure contexts. Add a textarea fallback for localhost/http.

Apply:

   const copyToClipboard = (text: string, stepIndex: number) => {
-    navigator.clipboard.writeText(text);
+    if (navigator.clipboard?.writeText) {
+      navigator.clipboard.writeText(text);
+    } else {
+      const ta = document.createElement("textarea");
+      ta.value = text;
+      ta.style.position = "fixed";
+      ta.style.opacity = "0";
+      document.body.appendChild(ta);
+      ta.select();
+      document.execCommand("copy");
+      document.body.removeChild(ta);
+    }
     setCopiedStep(stepIndex);
     setTimeout(() => setCopiedStep(null), 2000);
   };

50-93: Keep networks consistent across examples to reduce confusion (nit)

Examples mix mainnet (“USDC-mainnet”) with testnets (Sepolia). Prefer all‑testnet in docs samples.

Example:

-        supportedCurrencies: ["ETH-sepolia-sepolia", "FAU-sepolia", "USDC-mainnet"],
+        supportedCurrencies: ["ETH-sepolia-sepolia", "FAU-sepolia", "USDC-sepolia"],

Also applies to: 95-146

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 436b09d and c6835a0.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • app/components/homepage.tsx (1 hunks)
  • app/components/viem-account-demo.tsx (2 hunks)
  • app/page.tsx (1 hunks)
  • components/markdown-renderer/index.tsx (1 hunks)
  • components/ui/tabs.tsx (1 hunks)
  • package.json (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-09-18T13:45:16.493Z
Learnt from: bassgeta
PR: RequestNetwork/ui-registry#4
File: components/ui/collapsible.tsx:5-9
Timestamp: 2025-09-18T13:45:16.493Z
Learning: ShadCN UI components should not be modified from their standard implementations as they follow established patterns and are maintained externally. The radix-ui/react-collapsible package exports CollapsibleTrigger and CollapsibleContent with the full "Collapsible" prefix, unlike some other Radix primitives.

Applied to files:

  • components/ui/tabs.tsx
📚 Learning: 2025-09-18T13:44:43.566Z
Learnt from: bassgeta
PR: RequestNetwork/ui-registry#4
File: app/page.tsx:0-0
Timestamp: 2025-09-18T13:44:43.566Z
Learning: In the RequestNetwork UI registry showcase (app/page.tsx), using the zero address (0x0000000000000000000000000000000000000000) as the default for RECIPIENT_WALLET is acceptable because it's intended for demo/showcase purposes to avoid real transactions.

Applied to files:

  • app/page.tsx
📚 Learning: 2025-09-17T12:08:58.198Z
Learnt from: bassgeta
PR: RequestNetwork/ui-registry#1
File: registry/default/payment-widget/components/payment-confirmation.tsx:31-41
Timestamp: 2025-09-17T12:08:58.198Z
Learning: In the payment widget context (registry/default/payment-widget/context/payment-widget-context.tsx), connectedWalletAddress is properly derived as `walletAccount?.account?.address || address` which handles both custom WalletClient scenarios and wagmi-managed wallets, so components should use connectedWalletAddress from context rather than address from usePayment hook.

Applied to files:

  • app/page.tsx
📚 Learning: 2025-09-17T12:08:58.198Z
Learnt from: bassgeta
PR: RequestNetwork/ui-registry#1
File: registry/default/payment-widget/components/payment-confirmation.tsx:31-41
Timestamp: 2025-09-17T12:08:58.198Z
Learning: In the payment widget context (registry/default/payment-widget/context/payment-widget-context.tsx), connectedWalletAddress is properly derived as `walletAccount ? walletAccount.account?.address : address` which handles both custom WalletClient scenarios and wagmi-managed wallets, so components should use connectedWalletAddress from context rather than address from usePayment hook.

Applied to files:

  • app/page.tsx
🧬 Code graph analysis (3)
components/ui/tabs.tsx (1)
lib/utils.ts (1)
  • cn (4-6)
app/components/homepage.tsx (3)
app/components/payment-widget-wrapper.tsx (1)
  • PaymentWidgetWrapper (11-90)
app/components/viem-account-demo.tsx (1)
  • ViemAccountDemo (140-161)
components/markdown-renderer/index.tsx (1)
  • MarkdownRenderer (6-163)
app/page.tsx (1)
app/components/homepage.tsx (1)
  • HomePage (36-464)
🔇 Additional comments (4)
app/components/viem-account-demo.tsx (1)

140-152: Good: config and QueryClient memoization

Memoizing Wagmi config and QueryClient avoids re-instantiation churn when the demo remounts.

Also applies to: 154-160

components/ui/tabs.tsx (1)

8-23: Tabs wrappers look standard and solid

API mirrors Radix, class merging is correct, and displayName forwarding is in place.

Also applies to: 25-39, 40-55

app/components/homepage.tsx (2)

444-457: Ensure MarkdownRenderer is client-compatible

HomePage is a Client Component. Confirm MarkdownRenderer has "use client" (see my comment in components/markdown-renderer). Without it, Next.js will error at build.


148-191: Confirm stage registry URL is intended

The registry points to ui.stage.request.network. If this homepage targets production docs, switch to the prod registry.

@bassgeta bassgeta merged commit b8d2b9b into main Sep 19, 2025
1 check passed
@bassgeta bassgeta deleted the docs/how-to branch September 19, 2025 12:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants