Skip to content

feat: webhooks list in dashboard #7505

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 10, 2025

Conversation

arcoraven
Copy link
Contributor

@arcoraven arcoraven commented Jul 2, 2025

[Dashboard] Feature: Add Webhook Management UI

image.png

image.png

image.png

image.png

image.png

Notes for the reviewer

This PR adds a new webhook management UI to the dashboard, allowing users to create, edit, delete, and monitor webhooks. The implementation includes:

  • A new overview page for webhooks with a table to display all configured webhooks
  • Create/edit webhook modals with form validation
  • Topic selector for webhook event subscriptions
  • Delete confirmation with activity warning
  • Webhook metrics display showing request counts and error rates
  • API integration for webhook configuration management

How to test

Navigate to the webhooks section in a project to view the new UI. Create a new webhook, edit its configuration, and test the delete functionality. Verify that metrics are displayed correctly for existing webhooks.

Summary by CodeRabbit

  • New Features

    • Introduced comprehensive webhook management UI with creation, editing, deletion, and topic selection including JSON filter support.
    • Added webhook analytics dashboards displaying request status code distributions and latency percentiles with filtering by webhook and date range.
    • Enabled feature-flag controlled tabs for "Overview" and "Analytics" in the webhooks section.
    • Displayed detailed webhook metrics such as recent activity and error rates.
    • Added server-side PostHog integration for feature flag evaluation.
  • Bug Fixes

    • Enhanced error handling and user feedback during webhook configuration and analytics operations.
  • Chores

    • Renamed environment variable for PostHog API key.
    • Added PostHog Node.js client dependency.

PR-Codex overview

This PR introduces new webhook analytics features, enhancing the dashboard with interfaces for webhook statistics, latency, and request metrics. It also integrates posthog-node for feature flag management and modifies various components to support these changes.

Detailed summary

  • Added posthog-node dependency for feature flag management.
  • Introduced new TypeScript interfaces for webhook statistics: WebhookRequestStats, WebhookLatencyStats, WebhookSummaryStats.
  • Created CreateWebhookConfigModal and EditWebhookConfigModal components for managing webhooks.
  • Implemented WebhooksAnalytics and WebhookAnalyticsServer components for displaying webhook analytics.
  • Enhanced WebhookMetrics component to display metrics with error rates.
  • Updated WebhooksOverview to handle feature flags and redirect based on their status.
  • Added API functions for fetching webhook summary, requests, and latency data.
  • Improved UI components for user interaction, including modals and dropdowns for managing webhook configurations.

The following files were skipped due to too many changes: pnpm-lock.yaml

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Copy link

vercel bot commented Jul 2, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
docs-v2 ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 10, 2025 5:29pm
nebula ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 10, 2025 5:29pm
thirdweb_playground ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 10, 2025 5:29pm
thirdweb-www ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 10, 2025 5:29pm
wallet-ui ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 10, 2025 5:29pm

@vercel vercel bot temporarily deployed to Preview – docs-v2 July 2, 2025 14:09 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground July 2, 2025 14:09 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula July 2, 2025 14:09 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui July 2, 2025 14:09 Inactive
Copy link

changeset-bot bot commented Jul 2, 2025

⚠️ No Changeset found

Latest commit: 86e3aa8

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

coderabbitai bot commented Jul 2, 2025

Walkthrough

This update implements a comprehensive webhook management and analytics feature set in the dashboard application. It introduces backend API modules for managing webhook configurations and analytics, new React components for CRUD operations, topic selection, and analytics visualization, as well as server-side feature flag checks using PostHog. The webhooks section UI is refactored to support overview and analytics tabs, with dynamic tab rendering based on feature flags.

Changes

File(s) Change Summary
apps/dashboard/src/@/api/analytics.ts, apps/dashboard/src/@/types/analytics.ts Added API functions and types for fetching webhook analytics: summary, requests, and latency stats, with new TypeScript interfaces for analytics data structures.
apps/dashboard/src/@/api/webhook-configs.ts New module for CRUD operations on webhook configurations, including TypeScript interfaces for configs, topics, and API request/response payloads.
apps/dashboard/src/@/analytics/posthog-server.ts, apps/dashboard/package.json Introduced server-side PostHog feature flag checks with a singleton client; added posthog-node dependency.
apps/dashboard/.env.example Renamed PostHog API key environment variable and updated its default value.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/layout.tsx Dynamically renders "Overview" and "Analytics" tabs for webhooks based on a feature flag; adjusted tab paths.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx Refactored to fetch and display webhook configs, topics, and summary metrics; renders WebhooksOverview component.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/page.tsx New server component page for webhook analytics; fetches configs, stats, and renders analytics UI with filters and charts.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/contracts/page.tsx New server component page for contract webhook settings; fetches auth token and project, renders contracts content.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/... Added React components for: overview, CRUD modals (create, edit, delete), topic selection, configs table, metrics display, and analytics charts/filters. Components handle forms, modals, state, and API integration for webhook management and analytics.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/... New components for analytics filtering, charting, and server/client logic to display webhook request/latency stats and support responsive filtering.

Sequence Diagram(s)

Webhook Configuration Creation/Editing Flow

sequenceDiagram
  participant User
  participant WebhookConfigModal
  participant API (webhook-configs.ts)
  participant Backend

  User->>WebhookConfigModal: Open modal (create/edit)
  WebhookConfigModal->>User: Display form (fields, topic selector)
  User->>WebhookConfigModal: Enter data, submit form
  WebhookConfigModal->>API (webhook-configs.ts): createWebhookConfig / updateWebhookConfig
  API (webhook-configs.ts)->>Backend: POST/PATCH /webhook-configs
  Backend-->>API (webhook-configs.ts): Response (success/error)
  API (webhook-configs.ts)-->>WebhookConfigModal: Return result
  WebhookConfigModal-->>User: Show success/error, close modal, refresh table
Loading

Webhook Analytics Fetch and Display

sequenceDiagram
  participant User
  participant WebhooksAnalyticsPage
  participant API (analytics.ts)
  participant Backend
  participant WebhookAnalyticsCharts

  User->>WebhooksAnalyticsPage: Load analytics page with filters
  WebhooksAnalyticsPage->>API (analytics.ts): getWebhookRequests / getWebhookLatency
  API (analytics.ts)->>Backend: GET /webhook/requests /latency
  Backend-->>API (analytics.ts): Return stats data
  API (analytics.ts)-->>WebhooksAnalyticsPage: Return stats
  WebhooksAnalyticsPage->>WebhookAnalyticsCharts: Pass stats and configs
  WebhookAnalyticsCharts-->>User: Render charts/filters
Loading

Feature Flag Controlled Tab Rendering

sequenceDiagram
  participant Layout
  participant PostHogServer
  participant Backend

  Layout->>PostHogServer: isFeatureFlagEnabled("webhook-analytics-tab", userEmail)
  PostHogServer->>Backend: Query PostHog API
  Backend-->>PostHogServer: Return flag state
  PostHogServer-->>Layout: Return enabled/disabled
  Layout-->>Layout: Render tabs based on flag
Loading
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added the Dashboard Involves changes to the Dashboard. label Jul 2, 2025
Copy link
Contributor Author

arcoraven commented Jul 2, 2025


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • merge-queue - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@arcoraven arcoraven marked this pull request as ready for review July 2, 2025 14:09
@arcoraven arcoraven requested review from a team as code owners July 2, 2025 14:09
Copy link

codecov bot commented Jul 2, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 56.48%. Comparing base (aa1035d) to head (86e3aa8).
Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7505      +/-   ##
==========================================
- Coverage   56.50%   56.48%   -0.03%     
==========================================
  Files         906      906              
  Lines       58055    58055              
  Branches     4226     4221       -5     
==========================================
- Hits        32805    32790      -15     
- Misses      25140    25157      +17     
+ Partials      110      108       -2     
Flag Coverage Δ
packages 56.48% <ø> (-0.03%) ⬇️

see 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

github-actions bot commented Jul 2, 2025

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
thirdweb (esm) 63.14 KB (-0.09% 🔽) 1.3 s (-0.09% 🔽) 589 ms (+127.68% 🔺) 1.9 s
thirdweb (cjs) 353.26 KB (0%) 7.1 s (0%) 2 s (+11.79% 🔺) 9.1 s
thirdweb (minimal + tree-shaking) 5.7 KB (0%) 114 ms (0%) 176 ms (+1236.04% 🔺) 290 ms
thirdweb/chains (tree-shaking) 526 B (0%) 11 ms (0%) 114 ms (+1765.68% 🔺) 124 ms
thirdweb/react (minimal + tree-shaking) 19.59 KB (0%) 392 ms (0%) 185 ms (+503.99% 🔺) 577 ms

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: 5

🧹 Nitpick comments (5)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx (1)

26-35: Consider adding error handling for webhook data fetching.

While the current implementation gracefully handles missing data by using empty arrays, consider adding explicit error handling or logging for failed webhook config/topics API calls to aid in debugging.

You could add error logging like this:

  const [webhookConfigsResult, topicsResult] = await Promise.all([
    getWebhookConfigs({
      projectIdOrSlug: resolvedParams.project_slug,
      teamIdOrSlug: resolvedParams.team_slug,
    }),
    getAvailableTopics(),
  ]);

+ if (webhookConfigsResult.error) {
+   console.error("Failed to fetch webhook configs:", webhookConfigsResult.error);
+ }
+ if (topicsResult.error) {
+   console.error("Failed to fetch topics:", topicsResult.error);
+ }
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/delete-webhook-modal.tsx (1)

38-38: Remove unnecessary comment

This comment doesn't add value as the code is self-explanatory.

-  // Use real metrics data
  const requests24h = metrics?.totalRequests ?? 0;
apps/dashboard/src/@/api/webhook-configs.ts (3)

6-25: Consider exporting the nested topics interface.

The WebhookConfig interface is well-structured, but the nested topics interface could be extracted and exported for reusability, especially since it's also used in the Topic interface definition.

+export interface WebhookTopic {
+  id: string;
+  serviceName: string;
+  description: string;
+  createdAt: string;
+  updatedAt: string;
+  deletedAt: string | null;
+}

export interface WebhookConfig {
  id: string;
  teamId: string;
  projectId: string;
  destinationUrl: string;
  description: string;
  pausedAt: string | null;
  webhookSecret: string;
  createdAt: string;
  updatedAt: string;
  deletedAt: string | null;
-  topics: {
-    id: string;
-    serviceName: string;
-    description: string;
-    createdAt: string;
-    updatedAt: string;
-    deletedAt: string | null;
-  }[];
+  topics: WebhookTopic[];
}

27-73: Make interface exports consistent.

Some interfaces are exported while others are not. Consider exporting all interfaces that might be used by other modules for better type reusability and consistency.

-interface WebhookConfigsResponse {
+export interface WebhookConfigsResponse {
  data: WebhookConfig[];
  error?: string;
}

-interface CreateWebhookConfigRequest {
+export interface CreateWebhookConfigRequest {
  topicIds: string[];
  destinationUrl: string;
  description: string;
  isPaused?: boolean;
}

-interface CreateWebhookConfigResponse {
+export interface CreateWebhookConfigResponse {
  data: WebhookConfig;
  error?: string;
}

-interface TopicsResponse {
+export interface TopicsResponse {
  data: Topic[];
  error?: string;
}

-interface UpdateWebhookConfigRequest {
+export interface UpdateWebhookConfigRequest {
  destinationUrl?: string;
  topicIds?: string[];
  description?: string;
  isPaused?: boolean;
}

-interface UpdateWebhookConfigResponse {
+export interface UpdateWebhookConfigResponse {
  data: WebhookConfig;
  error?: string;
}

-interface DeleteWebhookConfigResponse {
+export interface DeleteWebhookConfigResponse {
  data: WebhookConfig;
  error?: string;
}

75-271: Consider centralizing the authentication check pattern.

All functions have identical authentication checking logic. Consider extracting this into a helper function to reduce code duplication and improve maintainability.

+async function withAuth<T>(
+  operation: (authToken: string) => Promise<T>,
+  errorData: T["data"]
+): Promise<T> {
+  const authToken = await getAuthToken();
+  if (!authToken) {
+    return {
+      data: errorData,
+      error: "Authentication required",
+    } as T;
+  }
+  return operation(authToken);
+}

This would allow each function to focus on its core logic while centralizing the authentication pattern.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7ab8808 and c78842d.

📒 Files selected for processing (16)
  • apps/dashboard/src/@/api/analytics.ts (2 hunks)
  • apps/dashboard/src/@/api/webhook-configs.ts (1 hunks)
  • apps/dashboard/src/@/api/webhook-metrics.ts (1 hunks)
  • apps/dashboard/src/@/types/analytics.ts (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/create-webhook-config-modal.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/delete-webhook-modal.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/edit-webhook-config-modal.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/overview.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/topic-selector-modal.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-config-modal.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-configs-table.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-metrics.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/contracts/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/hooks/use-webhook-metrics.ts (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/layout.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
`**/*.{ts,tsx}`: Write idiomatic TypeScript with explicit function declarations ...

**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity
Re-use shared types from @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)

📄 Source: CodeRabbit Inference Engine (CLAUDE.md)

List of files the instruction was applied to:

  • apps/dashboard/src/@/types/analytics.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/overview.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/contracts/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-metrics.tsx
  • apps/dashboard/src/@/api/webhook-metrics.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/create-webhook-config-modal.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-configs-table.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/delete-webhook-modal.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/topic-selector-modal.tsx
  • apps/dashboard/src/@/api/webhook-configs.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/layout.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-config-modal.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/edit-webhook-config-modal.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/hooks/use-webhook-metrics.ts
  • apps/dashboard/src/@/api/analytics.ts
`apps/{dashboard,playground-web}/**/*.{tsx,ts}`: Import UI primitives from `@/co...

apps/{dashboard,playground-web}/**/*.{tsx,ts}: Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Use NavLink for internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Use cn() from @/lib/utils for conditional class merging
Use design system tokens (e.g., bg-card, border-border, text-muted-foreground)
Expose className prop on root element for overrides in UI components
Server Components (Node edge): Start files with import "server-only";
Server Components: Read cookies/headers with next/headers
Server Components: Access server-only environment variables
Server Components: Perform heavy data fetching
Server Components: Implement redirect logic with redirect() from next/navigation
Client Components (browser): Begin files with 'use client';
Client Components: Handle interactive UI with React hooks (useState, useEffect, React Query, wallet hooks)
Client Components: Access browser APIs (localStorage, window, IntersectionObserver)
Client Components: Support fast transitions with prefetched data
Server Side Data Fetching: Always call getAuthToken() to retrieve JWT from cookies
Server Side Data Fetching: Use Authorization: Bearer header – never embed tokens in URLs
Server Side Data Fetching: Return typed results (Project[], User[]) – avoid any
Client Side Data Fetching: Wrap calls in React Query (@tanstack/react-query)
Client Side Data Fetching: Use descriptive, stable queryKeys for cache hits
Client Side Data Fetching: Configure staleTime/cacheTime based on freshness (default ≥ 60s)
Client Side Data Fetching: Keep tokens secret via internal API routes or server actions
Analytics Events: Never import posthog-js in server components

📄 Source: CodeRabbit Inference Engine (CLAUDE.md)

List of files the instruction was applied to:

  • apps/dashboard/src/@/types/analytics.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/overview.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/contracts/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-metrics.tsx
  • apps/dashboard/src/@/api/webhook-metrics.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/create-webhook-config-modal.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-configs-table.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/delete-webhook-modal.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/topic-selector-modal.tsx
  • apps/dashboard/src/@/api/webhook-configs.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/layout.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-config-modal.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/edit-webhook-config-modal.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/hooks/use-webhook-metrics.ts
  • apps/dashboard/src/@/api/analytics.ts
🧠 Learnings (17)
📓 Common learnings
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/hooks/**/*.{ts,tsx} : Use React Query (`@tanstack/react-query`) for all client data fetching.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: AmineAfia
PR: thirdweb-dev/js#7173
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/WebhooksTable.tsx:59-73
Timestamp: 2025-05-27T21:57:09.248Z
Learning: In the webhooks functionality, form validation prevents users from reaching test webhook functionality without entering a valid URL, ensuring data integrity before testing operations.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Components: Perform heavy data fetching
Learnt from: AmineAfia
PR: thirdweb-dev/js#7173
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/hooks/useTestWebhook.ts:87-89
Timestamp: 2025-05-27T21:57:57.175Z
Learning: In the webhook testing functionality, error detection using string matching (e.g., checking if error message includes "Failed to send test event") is intentional and based on specific error messages returned by the backend API, not frontend-generated errors.
apps/dashboard/src/@/types/analytics.ts (8)
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Analytics Events: Review `src/@/analytics/report.ts` for duplicates before adding new events
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to src/@/analytics/report.ts : Analytics Events: Event name should be human-readable `<subject> <verb>` (e.g. "contract deployed")
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/src/@/analytics/report.ts : Mandatory JSDoc: explain Why the event exists and Who owns it (`@username`).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Heavy data fetching that should not ship to the client (e.g. analytics, billing).
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Analytics Events: Never import `posthog-js` in server components
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/src/@/analytics/report.ts : Typed properties: accept a single `properties` object and pass it unchanged to `posthog.capture`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to src/@/analytics/report.ts : Analytics Events: Function should be named `report<Subject><Verb>` (PascalCase)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/overview.tsx (13)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : For notices & skeletons rely on `AnnouncementBanner`, `GenericLoadingPage`, `EmptyStateCard`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Components that listen to user events, animations or live updates.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Support fast transitions with prefetched data
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components (browser): Begin files with `'use client';`
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Expose `className` prop on root element for overrides in UI components
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Components: Perform heavy data fetching
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/hooks/**/*.{ts,tsx} : Use React Query (`@tanstack/react-query`) for all client data fetching.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/pages/*.client.tsx : Pages requiring fast transitions where data is prefetched on the client.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx (17)
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Components: Perform heavy data fetching
Learnt from: MananTank
PR: thirdweb-dev/js#7152
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx:41-48
Timestamp: 2025-05-26T16:28:50.772Z
Learning: The `projectMeta` prop is not required for the server-rendered `ContractTokensPage` component in the tokens shared page, unlike some other shared pages where it's needed for consistency.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Keep components pure; fetch data outside (server component or hook) and pass it down via props.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/pages/*.client.tsx : Pages requiring fast transitions where data is prefetched on the client.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Support fast transitions with prefetched data
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Local state or effects live inside; data fetching happens in hooks.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Components: Implement redirect logic with `redirect()` from `next/navigation`
Learnt from: MananTank
PR: thirdweb-dev/js#7434
File: apps/dashboard/src/app/(app)/team/~/~/contract/[chain]/[contractAddress]/components/project-selector.tsx:62-76
Timestamp: 2025-06-24T21:38:03.155Z
Learning: In the project-selector.tsx component for contract imports, the addToProject.mutate() call is intentionally not awaited (fire-and-forget pattern) to allow immediate navigation to the contract page while the import happens in the background. This is a deliberate design choice to prioritize user experience.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Use `NavLink` for internal navigation with automatic active states in dashboard and playground apps
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Redirect logic using `redirect()` from `next/navigation`.
Learnt from: MananTank
PR: thirdweb-dev/js#7152
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/shared-direct-listings-page.tsx:47-52
Timestamp: 2025-05-26T16:29:54.317Z
Learning: The `projectMeta` prop is not required for the server-rendered `ContractDirectListingsPage` component in the direct listings shared page, following the same pattern as other server components in the codebase where `projectMeta` is only needed for client components.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Side Data Fetching: Return typed results (`Project[]`, `User[]`) – avoid `any`
Learnt from: MananTank
PR: thirdweb-dev/js#7152
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/page.tsx:20-20
Timestamp: 2025-05-26T16:26:58.068Z
Learning: In team/project contract pages under routes like `/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/*`, users are always logged in by design. The hardcoded `isLoggedIn={true}` prop in these pages is intentional and correct, not a bug to be fixed.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/contracts/page.tsx (15)
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
Learnt from: MananTank
PR: thirdweb-dev/js#7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/launch-nft.tsx:155-160
Timestamp: 2025-06-10T00:46:58.580Z
Learning: In the dashboard application, the route structure for team and project navigation is `/team/[team_slug]/[project_slug]/...` without a `/project/` segment. Contract links should be formatted as `/team/${teamSlug}/${projectSlug}/contract/${chainId}/${contractAddress}`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: MananTank
PR: thirdweb-dev/js#7152
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx:41-48
Timestamp: 2025-05-26T16:28:50.772Z
Learning: The `projectMeta` prop is not required for the server-rendered `ContractTokensPage` component in the tokens shared page, unlike some other shared pages where it's needed for consistency.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Components: Perform heavy data fetching
Learnt from: MananTank
PR: thirdweb-dev/js#7152
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/page.tsx:20-20
Timestamp: 2025-05-26T16:26:58.068Z
Learning: In team/project contract pages under routes like `/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/*`, users are always logged in by design. The hardcoded `isLoggedIn={true}` prop in these pages is intentional and correct, not a bug to be fixed.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : For notices & skeletons rely on `AnnouncementBanner`, `GenericLoadingPage`, `EmptyStateCard`.
Learnt from: MananTank
PR: thirdweb-dev/js#7434
File: apps/dashboard/src/app/(app)/team/~/~/contract/[chain]/[contractAddress]/components/project-selector.tsx:62-76
Timestamp: 2025-06-24T21:38:03.155Z
Learning: In the project-selector.tsx component for contract imports, the addToProject.mutate() call is intentionally not awaited (fire-and-forget pattern) to allow immediate navigation to the contract page while the import happens in the background. This is a deliberate design choice to prioritize user experience.
Learnt from: MananTank
PR: thirdweb-dev/js#7152
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/page.tsx:2-10
Timestamp: 2025-05-26T16:28:10.079Z
Learning: In Next.js 14+, the `params` object in page components is always a Promise that needs to be awaited, so the correct typing is `params: Promise<ParamsType>` rather than `params: ParamsType`.
Learnt from: MananTank
PR: thirdweb-dev/js#7152
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx:43-49
Timestamp: 2025-05-26T16:31:02.480Z
Learning: In the thirdweb dashboard codebase, when `redirectToContractLandingPage()` is called, an explicit return statement is not required afterward because the function internally calls Next.js's `redirect()` which throws an error to halt execution.
Learnt from: MananTank
PR: thirdweb-dev/js#7152
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/shared-analytics-page.tsx:33-39
Timestamp: 2025-05-26T16:30:24.965Z
Learning: In the thirdweb dashboard codebase, redirectToContractLandingPage function already handles execution termination internally (likely using Next.js redirect() which throws an exception), so no explicit return statement is needed after calling it.
Learnt from: MananTank
PR: thirdweb-dev/js#7152
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/shared-direct-listings-page.tsx:47-52
Timestamp: 2025-05-26T16:29:54.317Z
Learning: The `projectMeta` prop is not required for the server-rendered `ContractDirectListingsPage` component in the direct listings shared page, following the same pattern as other server components in the codebase where `projectMeta` is only needed for client components.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Components: Implement redirect logic with `redirect()` from `next/navigation`
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-metrics.tsx (12)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : For notices & skeletons rely on `AnnouncementBanner`, `GenericLoadingPage`, `EmptyStateCard`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Components that listen to user events, animations or live updates.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Analytics Events: Never import `posthog-js` in server components
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Components: Perform heavy data fetching
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Local state or effects live inside; data fetching happens in hooks.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/hooks/**/*.{ts,tsx} : Use React Query (`@tanstack/react-query`) for all client data fetching.
Learnt from: MananTank
PR: thirdweb-dev/js#7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx:15-17
Timestamp: 2025-05-27T19:54:55.885Z
Learning: The `fetchDashboardContractMetadata` function from "@3rdweb-sdk/react/hooks/useDashboardContractMetadata" has internal error handlers for all promises and cannot throw errors, so external error handling is not needed when calling this function.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : When you need access to browser APIs (localStorage, window, IntersectionObserver etc.).
apps/dashboard/src/@/api/webhook-metrics.ts (9)
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/hooks/**/*.{ts,tsx} : Prefer API routes or server actions to keep tokens secret; the browser only sees relative paths.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Heavy data fetching that should not ship to the client (e.g. analytics, billing).
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Components: Perform heavy data fetching
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Side Data Fetching: Return typed results (`Project[]`, `User[]`) – avoid `any`
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Export default async functions without `'use client';` – they run on the Node edge.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Return typed results (`Project[]`, `User[]`, …) – avoid `any`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Co-locate data helpers under `@/api/**` and mark them with "server-only".
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Analytics Events: Never import `posthog-js` in server components
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/create-webhook-config-modal.tsx (10)
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Accept a typed `props` object and export a named function (`export function MyComponent()`).
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : For notices & skeletons rely on `AnnouncementBanner`, `GenericLoadingPage`, `EmptyStateCard`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to apps/{dashboard,playground-web}/**/feature/components/**/*.{tsx,ts} : Group feature-specific components under `feature/components/*` with barrel `index.ts`
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Prefer composable primitives over custom markup: `Button`, `Input`, `Select`, `Tabs`, `Card`, `Sidebar`, `Separator`, `Badge`.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-configs-table.tsx (13)
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/hooks/**/*.{ts,tsx} : Use React Query (`@tanstack/react-query`) for all client data fetching.
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Components: Perform heavy data fetching
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : For notices & skeletons rely on `AnnouncementBanner`, `GenericLoadingPage`, `EmptyStateCard`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Support fast transitions with prefetched data
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Components that listen to user events, animations or live updates.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Side Data Fetching: Wrap calls in React Query (`@tanstack/react-query`)
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Use design system tokens (e.g., `bg-card`, `border-border`, `text-muted-foreground`)
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Side Data Fetching: Use descriptive, stable `queryKeys` for cache hits
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/delete-webhook-modal.tsx (10)
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : For notices & skeletons rely on `AnnouncementBanner`, `GenericLoadingPage`, `EmptyStateCard`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Components that listen to user events, animations or live updates.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Prefer composable primitives over custom markup: `Button`, `Input`, `Select`, `Tabs`, `Card`, `Sidebar`, `Separator`, `Badge`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Accept a typed `props` object and export a named function (`export function MyComponent()`).
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/topic-selector-modal.tsx (10)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : For notices & skeletons rely on `AnnouncementBanner`, `GenericLoadingPage`, `EmptyStateCard`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Components that listen to user events, animations or live updates.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Prefer composable primitives over custom markup: `Button`, `Input`, `Select`, `Tabs`, `Card`, `Sidebar`, `Separator`, `Badge`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Accept a typed `props` object and export a named function (`export function MyComponent()`).
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Support fast transitions with prefetched data
apps/dashboard/src/@/api/webhook-configs.ts (17)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Export default async functions without `'use client';` – they run on the Node edge.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Heavy data fetching that should not ship to the client (e.g. analytics, billing).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/hooks/**/*.{ts,tsx} : Prefer API routes or server actions to keep tokens secret; the browser only sees relative paths.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to packages/thirdweb/src/exports/**/*.{ts,tsx} : Export everything via `exports/` directory, grouped by feature in the public API of the SDK
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Co-locate data helpers under `@/api/**` and mark them with "server-only".
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Client-side only: never import `posthog-js` in server components.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Return typed results (`Project[]`, `User[]`, …) – avoid `any`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Side Data Fetching: Keep tokens secret via internal API routes or server actions
Learnt from: MananTank
PR: thirdweb-dev/js#7356
File: apps/nebula/src/app/not-found.tsx:1-1
Timestamp: 2025-06-17T18:30:52.976Z
Learning: In the thirdweb/js project, the React namespace is available for type annotations (like React.FC) without needing to explicitly import React. This is project-specific configuration that differs from typical TypeScript/React setups.
Learnt from: MananTank
PR: thirdweb-dev/js#7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenTransfers.ts:41-44
Timestamp: 2025-05-27T19:56:16.920Z
Learning: When reviewing hooks that use environment variables like NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID for API calls, MananTank prefers not to add explicit validation checks for these variables, trusting they will be set in the deployment environment.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Side Data Fetching: Use `Authorization: Bearer` header – never embed tokens in URLs
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Components: Perform heavy data fetching
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Reading cookies/headers with `next/headers` (`getAuthToken()`, `cookies()`).
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/layout.tsx (11)
Learnt from: MananTank
PR: thirdweb-dev/js#7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/launch-nft.tsx:155-160
Timestamp: 2025-06-10T00:46:58.580Z
Learning: In the dashboard application, the route structure for team and project navigation is `/team/[team_slug]/[project_slug]/...` without a `/project/` segment. Contract links should be formatted as `/team/${teamSlug}/${projectSlug}/contract/${chainId}/${contractAddress}`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Use `NavLink` for internal navigation with automatic active states in dashboard and playground apps
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Use `NavLink` (`@/components/ui/NavLink`) for internal navigation so active states are handled automatically.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/layout.tsx : Layouts should reuse `SidebarLayout` / `FullWidthSidebarLayout` (`@/components/blocks/SidebarLayout`).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/layout.tsx : Building layout shells (`layout.tsx`) and top-level pages that mainly assemble data.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to apps/{dashboard,playground-web}/**/feature/components/**/*.{tsx,ts} : Group feature-specific components under `feature/components/*` with barrel `index.ts`
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: MananTank
PR: thirdweb-dev/js#7152
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/nfts/page.tsx:20-20
Timestamp: 2025-05-26T16:26:58.068Z
Learning: In team/project contract pages under routes like `/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/*`, users are always logged in by design. The hardcoded `isLoggedIn={true}` prop in these pages is intentional and correct, not a bug to be fixed.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-config-modal.tsx (10)
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/hooks/**/*.{ts,tsx} : Use React Query (`@tanstack/react-query`) for all client data fetching.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Accept a typed `props` object and export a named function (`export function MyComponent()`).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : For notices & skeletons rely on `AnnouncementBanner`, `GenericLoadingPage`, `EmptyStateCard`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Components that listen to user events, animations or live updates.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Local state or effects live inside; data fetching happens in hooks.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/edit-webhook-config-modal.tsx (10)
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Accept a typed `props` object and export a named function (`export function MyComponent()`).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : For notices & skeletons rely on `AnnouncementBanner`, `GenericLoadingPage`, `EmptyStateCard`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Components that listen to user events, animations or live updates.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to apps/{dashboard,playground-web}/**/feature/components/**/*.{tsx,ts} : Group feature-specific components under `feature/components/*` with barrel `index.ts`
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/hooks/use-webhook-metrics.ts (12)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/hooks/**/*.{ts,tsx} : Use React Query (`@tanstack/react-query`) for all client data fetching.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Side Data Fetching: Wrap calls in React Query (`@tanstack/react-query`)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/hooks/**/*.{ts,tsx} : Keep `queryKey` stable and descriptive for cache hits.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/hooks/**/*.{ts,tsx} : Configure `staleTime` / `cacheTime` according to freshness requirements.
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Side Data Fetching: Use descriptive, stable `queryKeys` for cache hits
Learnt from: MananTank
PR: thirdweb-dev/js#7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx:15-17
Timestamp: 2025-05-27T19:54:55.885Z
Learning: The `fetchDashboardContractMetadata` function from "@3rdweb-sdk/react/hooks/useDashboardContractMetadata" has internal error handlers for all promises and cannot throw errors, so external error handling is not needed when calling this function.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Heavy data fetching that should not ship to the client (e.g. analytics, billing).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : When you need access to browser APIs (localStorage, window, IntersectionObserver etc.).
apps/dashboard/src/@/api/analytics.ts (11)
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Analytics Events: Review `src/@/analytics/report.ts` for duplicates before adding new events
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Heavy data fetching that should not ship to the client (e.g. analytics, billing).
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Analytics Events: Never import `posthog-js` in server components
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/src/@/analytics/report.ts : Mandatory JSDoc: explain Why the event exists and Who owns it (`@username`).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Export default async functions without `'use client';` – they run on the Node edge.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to src/@/analytics/report.ts : Analytics Events: Event name should be human-readable `<subject> <verb>` (e.g. "contract deployed")
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to src/wallets/**/*.{ts,tsx} : Unified `Wallet` and `Account` interfaces in wallet architecture
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Side Data Fetching: Return typed results (`Project[]`, `User[]`) – avoid `any`
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Return typed results (`Project[]`, `User[]`, …) – avoid `any`.
🧬 Code Graph Analysis (7)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx (2)
apps/dashboard/src/@/api/webhook-configs.ts (2)
  • getWebhookConfigs (75-112)
  • getAvailableTopics (155-189)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/overview.tsx (1)
  • Overview (13-27)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-metrics.tsx (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/hooks/use-webhook-metrics.ts (1)
  • useWebhookMetrics (14-37)
packages/thirdweb/src/react/web/ui/components/Spinner.tsx (1)
  • Spinner (11-34)
apps/dashboard/src/@/api/webhook-metrics.ts (2)
apps/dashboard/src/@/types/analytics.ts (1)
  • WebhookSummaryStats (75-83)
apps/dashboard/src/@/api/analytics.ts (1)
  • getWebhookMetrics (429-472)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/topic-selector-modal.tsx (1)
apps/dashboard/src/@/api/webhook-configs.ts (1)
  • Topic (44-51)
apps/dashboard/src/@/api/webhook-configs.ts (1)
apps/dashboard/src/@/constants/public-envs.ts (1)
  • NEXT_PUBLIC_THIRDWEB_API_HOST (18-19)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/hooks/use-webhook-metrics.ts (2)
apps/dashboard/src/@/types/analytics.ts (1)
  • WebhookSummaryStats (75-83)
apps/dashboard/src/@/api/webhook-metrics.ts (1)
  • getWebhookMetricsAction (6-16)
apps/dashboard/src/@/api/analytics.ts (1)
apps/dashboard/src/@/types/analytics.ts (1)
  • WebhookSummaryStats (75-83)
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: Unit Tests
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: Lint Packages
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: Size
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (18)
apps/dashboard/src/@/types/analytics.ts (1)

75-83: Well-structured interface definition.

The WebhookSummaryStats interface follows TypeScript best practices with explicit typing and descriptive property names. The use of Record<string, unknown> for errorBreakdown provides appropriate flexibility for dynamic error data structures.

apps/dashboard/src/@/api/analytics.ts (2)

16-16: LGTM: Proper type import.

The WebhookSummaryStats type is correctly imported and integrated with the existing analytics types.


429-472: Excellent implementation following established patterns.

The getWebhookMetrics function is well-implemented and follows the exact patterns used by other analytics functions in this file:

  • Proper TypeScript typing with explicit return type
  • Consistent parameter structure with required and optional fields
  • Uses the shared fetchAnalytics utility for authentication and request handling
  • Implements consistent error handling by logging and returning empty array
  • Follows the established API endpoint pattern with v2/webhook/summary
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/layout.tsx (2)

28-29: Good navigation structure with exact matching.

The "Overview" tab with exactMatch: true is properly configured for the base webhooks path, ensuring correct active state handling.


31-34: Well-organized tab separation.

The addition of a dedicated "Contracts" tab provides clear separation of webhook functionality and follows the established route pattern for team/project navigation.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/edit-webhook-config-modal.tsx (1)

1-25: Clean wrapper component with proper separation of concerns.

The EditWebhookConfigModal component follows best practices:

  • Proper TypeScript interface with well-typed props
  • Exports named function as per coding guidelines
  • Clean delegation to underlying WebhookConfigModal with appropriate mode
  • Good separation of concerns by wrapping the generic modal for specific edit functionality
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/create-webhook-config-modal.tsx (1)

1-23: Consistent wrapper component design.

The CreateWebhookConfigModal component follows the same excellent patterns as the edit modal:

  • Proper TypeScript interface definition
  • Named function export following coding guidelines
  • Clean delegation to WebhookConfigModal with mode="create"
  • Consistent prop structure for team/project context

The symmetry between create and edit modals provides a cohesive API design.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/overview.tsx (1)

1-27: LGTM - Clean wrapper component implementation!

The component follows best practices with proper client component declaration, well-defined TypeScript interface, and clean prop delegation to the table component.

apps/dashboard/src/@/api/webhook-metrics.ts (1)

1-16: LGTM - Proper server action implementation!

The server action correctly wraps the analytics API call with appropriate typing and result handling.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/hooks/use-webhook-metrics.ts (1)

14-37: LGTM - Well-implemented React Query hook!

The hook follows best practices with stable query keys, proper cache configuration, conditional enabling, and good TypeScript typing.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/contracts/page.tsx (1)

7-45: LGTM - Excellent server component implementation!

The component properly handles async params, uses concurrent data fetching with Promise.all, includes appropriate error handling, and follows established patterns for server components in the codebase.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx (1)

26-44: LGTM - Excellent server-side data fetching pattern!

The refactored page properly separates server-side data fetching from client-side rendering, uses concurrent API calls for better performance, and maintains clean prop passing to the Overview component.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/topic-selector-modal.tsx (1)

1-127: Well-implemented topic selection modal

The component demonstrates good practices:

  • Efficient grouping and sorting logic
  • Proper state management with temporary selection
  • Accessible form controls with proper labels
  • Good UX with cancel/save behavior
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-config-modal.tsx (1)

1-328: Excellent webhook configuration modal implementation

The component demonstrates several best practices:

  • Comprehensive form validation with security in mind (HTTPS-only URLs)
  • Proper handling of both create and edit modes
  • Good UX with form reset behavior and loading states
  • Well-integrated topic selection with the child modal
apps/dashboard/src/@/api/webhook-configs.ts (4)

1-4: LGTM! Proper server-side API setup.

The "use server" directive and imports are correctly configured for server-side API functions. The authentication token import and API host constant follow the established patterns.


75-112: LGTM! Well-implemented function with proper error handling.

The getWebhookConfigs function follows best practices with proper authentication, error handling, and typed responses. The error case correctly returns an empty array matching the expected response type.


155-189: LGTM! Function correctly handles topic fetching.

The getAvailableTopics function is well-implemented with proper error handling and correct response types. The error case appropriately returns an empty array matching the expected Topic[] type.


191-231: Replace type assertion with proper null handling.

The error cases use {} as WebhookConfig which is a type assertion hack that could lead to runtime issues. Consider using a more explicit approach.

  if (!authToken) {
    return {
-      data: {} as WebhookConfig,
+      data: null as unknown as WebhookConfig,
      error: "Authentication required",
    };
  }
  if (!response.ok) {
    const errorText = await response.text();
    return {
-      data: {} as WebhookConfig,
+      data: null as unknown as WebhookConfig,
      error: `Failed to update webhook config: ${errorText}`,
    };
  }
⛔ Skipped due to learnings
Learnt from: AmineAfia
PR: thirdweb-dev/js#7173
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/hooks/useTestWebhook.ts:87-89
Timestamp: 2025-05-27T21:57:57.175Z
Learning: In the webhook testing functionality, error detection using string matching (e.g., checking if error message includes "Failed to send test event") is intentional and based on specific error messages returned by the backend API, not frontend-generated errors.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Side Data Fetching: Use `Authorization: Bearer` header – never embed tokens in URLs
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to **/*.{ts,tsx} : Avoid `any` and `unknown` unless unavoidable; narrow generics when possible
Learnt from: MananTank
PR: thirdweb-dev/js#7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts:49-49
Timestamp: 2025-05-27T19:55:25.056Z
Learning: In the ERC20 public pages token price data hook (`useTokenPriceData.ts`), direct array access on `json.data[0]` without optional chaining is intentionally correct and should not be changed to use safety checks.
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
Learnt from: MananTank
PR: thirdweb-dev/js#7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/single-upload/attributes.tsx:24-25
Timestamp: 2025-06-10T00:49:12.707Z
Learning: In React Hook Form with TypeScript generics, when using useFieldArray with a generic form type T that extends a specific interface, it's often necessary to use type assertions like `as unknown as UseFormReturn<WithAttributes>` rather than trying to use `as keyof T`. The type assertion approach works better because useFieldArray needs specific type information about the array field structure, and the generic constraint ensures the field exists safely.

@arcoraven arcoraven force-pushed the ph/07-02-feat_webhooks_list_in_dashboard branch from c78842d to 586297d Compare July 2, 2025 15:06
@vercel vercel bot temporarily deployed to Preview – docs-v2 July 2, 2025 15:06 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground July 2, 2025 15:06 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui July 2, 2025 15:06 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula July 2, 2025 15:06 Inactive
Copy link
Member

@MananTank MananTank left a comment

Choose a reason for hiding this comment

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

Getting error when trying to update the webhook

@vercel vercel bot temporarily deployed to Preview – thirdweb_playground July 10, 2025 16:30 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 July 10, 2025 16:30 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui July 10, 2025 16:30 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula July 10, 2025 16:30 Inactive
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: 1

♻️ Duplicate comments (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-config-modal.tsx (2)

75-84: Fix type safety issue with webhookConfig access in edit mode

The code uses optional chaining on webhookConfig when isEditMode is true, but doesn't verify that webhookConfig exists. This can cause runtime issues if the component is used incorrectly.

Add proper type guards to ensure webhookConfig is defined when in edit mode:

  const form = useForm<FormValues>({
    defaultValues: {
-      description: isEditMode ? webhookConfig?.description || "" : "",
-      destinationUrl: isEditMode ? webhookConfig?.destinationUrl || "" : "",
-      isPaused: isEditMode ? !!webhookConfig?.pausedAt : false,
-      topics:
-        isEditMode && webhookConfig?.topics
-          ? webhookConfig.topics.map((t) => ({
-              id: t.id,
-              filters: t.filters,
-            }))
-          : [],
+      description: isEditMode && webhookConfig ? webhookConfig.description || "" : "",
+      destinationUrl: isEditMode && webhookConfig ? webhookConfig.destinationUrl || "" : "",
+      isPaused: isEditMode && webhookConfig ? !!webhookConfig.pausedAt : false,
+      topics:
+        isEditMode && webhookConfig?.topics
+          ? webhookConfig.topics.map((t) => ({
+              id: t.id,
+              filters: t.filters,
+            }))
+          : [],
    },
    resolver: zodResolver(formSchema),
  });

263-263: Display user-friendly topic names instead of IDs

The topic badges show topic.id which is not user-friendly. Users would benefit from seeing descriptive topic names.

-                                {topic.id}
+                                {/* Display topic name if available, fallback to ID */}
+                                {props.topics.find(t => t.id === topic.id)?.name || topic.id}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ae16bc9 and 07932a9.

📒 Files selected for processing (5)
  • apps/dashboard/src/@/api/webhook-configs.ts (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsFilter.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/topic-selector-modal.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-config-modal.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-configs-table.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsFilter.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/topic-selector-modal.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-configs-table.tsx
  • apps/dashboard/src/@/api/webhook-configs.ts
🧰 Additional context used
📓 Path-based instructions (2)
`**/*.{ts,tsx}`: Write idiomatic TypeScript with explicit function declarations ...

**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity
Re-use shared types from @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)

📄 Source: CodeRabbit Inference Engine (CLAUDE.md)

List of files the instruction was applied to:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-config-modal.tsx
`apps/{dashboard,playground-web}/**/*.{tsx,ts}`: Import UI primitives from `@/co...

apps/{dashboard,playground-web}/**/*.{tsx,ts}: Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Use NavLink for internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Use cn() from @/lib/utils for conditional class merging
Use design system tokens (e.g., bg-card, border-border, text-muted-foreground)
Expose className prop on root element for overrides in UI components
Server Components (Node edge): Start files with import "server-only";
Server Components: Read cookies/headers with next/headers
Server Components: Access server-only environment variables
Server Components: Perform heavy data fetching
Server Components: Implement redirect logic with redirect() from next/navigation
Client Components (browser): Begin files with 'use client';
Client Components: Handle interactive UI with React hooks (useState, useEffect, React Query, wallet hooks)
Client Components: Access browser APIs (localStorage, window, IntersectionObserver)
Client Components: Support fast transitions with prefetched data
Server Side Data Fetching: Always call getAuthToken() to retrieve JWT from cookies
Server Side Data Fetching: Use Authorization: Bearer header – never embed tokens in URLs
Server Side Data Fetching: Return typed results (Project[], User[]) – avoid any
Client Side Data Fetching: Wrap calls in React Query (@tanstack/react-query)
Client Side Data Fetching: Use descriptive, stable queryKeys for cache hits
Client Side Data Fetching: Configure staleTime/cacheTime based on freshness (default ≥ 60s)
Client Side Data Fetching: Keep tokens secret via internal API routes or server actions
Analytics Events: Never import posthog-js in server components

📄 Source: CodeRabbit Inference Engine (CLAUDE.md)

List of files the instruction was applied to:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-config-modal.tsx
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Surface breaking changes prominently in PR descriptions
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Analytics Events: Never import `posthog-js` in server components
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/hooks/**/*.{ts,tsx} : Use React Query (`@tanstack/react-query`) for all client data fetching.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Heavy data fetching that should not ship to the client (e.g. analytics, billing).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Components: Perform heavy data fetching
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-config-modal.tsx (28)
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: arcoraven
PR: thirdweb-dev/js#7505
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx:186-204
Timestamp: 2025-07-10T10:18:33.238Z
Learning: The ThirdwebBarChart component in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx does not accept standard accessibility props like `aria-label` and `role` in its TypeScript interface, causing compilation errors when added.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/hooks/**/*.{ts,tsx} : Use React Query (`@tanstack/react-query`) for all client data fetching.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : For notices & skeletons rely on `AnnouncementBanner`, `GenericLoadingPage`, `EmptyStateCard`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Components that listen to user events, animations or live updates.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Accept a typed `props` object and export a named function (`export function MyComponent()`).
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Side Data Fetching: Wrap calls in React Query (`@tanstack/react-query`)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/pages/*.client.tsx : Pages requiring fast transitions where data is prefetched on the client.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Side Data Fetching: Use descriptive, stable `queryKeys` for cache hits
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Keep components pure; fetch data outside (server component or hook) and pass it down via props.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Support fast transitions with prefetched data
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Side Data Fetching: Configure `staleTime`/`cacheTime` based on freshness (default ≥ 60s)
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Components: Perform heavy data fetching
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Side Data Fetching: Keep tokens secret via internal API routes or server actions
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/hooks/**/*.{ts,tsx} : Keep `queryKey` stable and descriptive for cache hits.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to src/@/analytics/report.ts : Analytics Events: Event name should be human-readable `<subject> <verb>` (e.g. "contract deployed")
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Prefer composable primitives over custom markup: `Button`, `Input`, `Select`, `Tabs`, `Card`, `Sidebar`, `Separator`, `Badge`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Use design system tokens (e.g., `bg-card`, `border-border`, `text-muted-foreground`)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Stick to design-tokens: background (`bg-card`), borders (`border-border`), muted text (`text-muted-foreground`) etc.
Learnt from: MananTank
PR: thirdweb-dev/js#7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/launch-nft.tsx:153-226
Timestamp: 2025-06-10T00:50:20.795Z
Learning: In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/launch-nft.tsx, the updateStatus function correctly expects a complete MultiStepState["status"] object. For pending states, { type: "pending" } is the entire status object. For error states, { type: "error", message: React.ReactNode } is the entire status object. The current code incorrectly spreads the entire step object instead of passing just the status object.
Learnt from: MananTank
PR: thirdweb-dev/js#7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts:49-49
Timestamp: 2025-05-27T19:55:25.056Z
Learning: In the ERC20 public pages token price data hook (`useTokenPriceData.ts`), direct array access on `json.data[0]` without optional chaining is intentionally correct and should not be changed to use safety checks.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to **/*.{ts,tsx} : Comment only ambiguous logic; avoid restating TypeScript in prose
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to **/*.{ts,tsx} : Avoid `any` and `unknown` unless unavoidable; narrow generics when possible
Learnt from: MananTank
PR: thirdweb-dev/js#7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenTransfers.ts:41-44
Timestamp: 2025-05-27T19:56:16.920Z
Learning: When reviewing hooks that use environment variables like NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID for API calls, MananTank prefers not to add explicit validation checks for these variables, trusting they will be set in the deployment environment.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Lint Packages
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: Build Packages
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: Size
  • GitHub Check: Unit Tests
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (3)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-config-modal.tsx (3)

37-52: Form schema validation looks comprehensive

The Zod schema properly validates all required fields with appropriate constraints: non-empty description, HTTPS URL requirement, and at least one topic selection.


89-148: Mutation handling follows React Query best practices

The mutation setup properly handles both create and edit modes, includes comprehensive error handling with toast notifications, and correctly invalidates the query cache on success.


335-344: TopicSelectorModal integration is well-implemented

The nested modal for topic selection properly manages state and form integration, with clean separation of concerns.

@arcoraven arcoraven enabled auto-merge (squash) July 10, 2025 17:07
@arcoraven arcoraven added the merge-queue Adds the pull request to Graphite's merge queue. label Jul 10, 2025
Copy link
Contributor Author

arcoraven commented Jul 10, 2025

Merge activity

# [Dashboard] Feature: Add Webhook Management UI

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/vKjRiOG6EUjD7XH4cppU/38dbe90b-2bd9-47b6-b190-3c257e99d2fe.png)

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/vKjRiOG6EUjD7XH4cppU/d0a40295-c1c7-45c5-9b23-224a2a631b83.png)

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/vKjRiOG6EUjD7XH4cppU/42d5337d-fcfe-4ef7-a349-1f596013e003.png)

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/vKjRiOG6EUjD7XH4cppU/b7b89fe6-a5f7-4961-b927-bfc754c6665f.png)

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/vKjRiOG6EUjD7XH4cppU/88916c15-a501-4ceb-9267-a23290f683b9.png)

## Notes for the reviewer
This PR adds a new webhook management UI to the dashboard, allowing users to create, edit, delete, and monitor webhooks. The implementation includes:

- A new overview page for webhooks with a table to display all configured webhooks
- Create/edit webhook modals with form validation
- Topic selector for webhook event subscriptions
- Delete confirmation with activity warning
- Webhook metrics display showing request counts and error rates
- API integration for webhook configuration management

## How to test
Navigate to the webhooks section in a project to view the new UI. Create a new webhook, edit its configuration, and test the delete functionality. Verify that metrics are displayed correctly for existing webhooks.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Introduced a comprehensive webhooks management interface, including creation, editing, deletion, and topic selection with optional JSON filters.
  * Added analytics dashboards for webhooks, featuring charts for request status codes and latency percentiles, with filtering by webhook and date range.
  * Implemented feature flag-based tab navigation for "Overview" and "Analytics" in the webhooks section.
  * Provided detailed webhook metrics, including recent activity and error rates.

* **Bug Fixes**
  * Improved error handling and user feedback for webhook configuration and analytics operations.

* **Chores**
  * Added PostHog server-side analytics integration.
  * Updated environment variable naming for analytics configuration.
  * Added new dependency for analytics support.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces webhook analytics features and enhances the webhook management system, including new types for webhook statistics, UI components for creating and editing webhooks, and improvements in data fetching and handling.

### Detailed summary
- Added `posthog-node` dependency for server-side analytics.
- Updated environment variable from `NEXT_PUBLIC_POSTHOG_API_KEY` to `NEXT_PUBLIC_POSTHOG_KEY`.
- Introduced interfaces for `WebhookRequestStats`, `WebhookLatencyStats`, and `WebhookSummaryStats`.
- Created `CreateWebhookConfigModal` and `EditWebhookConfigModal` components for managing webhooks.
- Implemented `WebhooksAnalytics` and `WebhookAnalyticsServer` components for displaying analytics data.
- Enhanced `WebhookMetrics` to show metrics and error rates.
- Added `isFeatureFlagEnabled` function for feature flag checks.
- Implemented data fetching functions for webhook metrics in `analytics.ts`.
- Updated the webhook configuration management with new API endpoints and improved error handling.
- Created `TopicSelectorModal` for selecting topics with optional filters.
- Improved UI components for better user experience in managing webhooks.

> The following files were skipped due to too many changes: `pnpm-lock.yaml`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
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: 0

🧹 Nitpick comments (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx (2)

4-9: Consider using import aliases for cleaner imports.

The deep relative import paths (../../../../../../../@/api/...) could be simplified using proper import aliases if configured in your TypeScript/Next.js setup.

-import { getWebhookSummary } from "../../../../../../../@/api/analytics";
-import {
-  getAvailableTopics,
-  getWebhookConfigs,
-} from "../../../../../../../@/api/webhook-configs";
+import { getWebhookSummary } from "@/api/analytics";
+import {
+  getAvailableTopics,
+  getWebhookConfigs,
+} from "@/api/webhook-configs";

56-56: Fix misplaced comment for clarity.

The comment // 24 hours ago is placed after the teamId assignment but refers to the from parameter calculation on line 53.

-        teamId: project.teamId, // 24 hours ago
+        teamId: project.teamId,

Or move the comment to the appropriate line:

-        from: new Date(Date.now() - 24 * 60 * 60 * 1000),
+        from: new Date(Date.now() - 24 * 60 * 60 * 1000), // 24 hours ago
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 07932a9 and 86e3aa8.

📒 Files selected for processing (22)
  • apps/dashboard/.env.example (1 hunks)
  • apps/dashboard/package.json (1 hunks)
  • apps/dashboard/src/@/analytics/posthog-server.ts (1 hunks)
  • apps/dashboard/src/@/api/analytics.ts (2 hunks)
  • apps/dashboard/src/@/api/webhook-configs.ts (1 hunks)
  • apps/dashboard/src/@/types/analytics.ts (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsFilter.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsServer.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhooksAnalytics.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/create-webhook-config-modal.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/delete-webhook-modal.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/edit-webhook-config-modal.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/overview.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/topic-selector-modal.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-config-modal.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-configs-table.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-metrics.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/contracts/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/layout.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx (2 hunks)
✅ Files skipped from review due to trivial changes (2)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/delete-webhook-modal.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx
🚧 Files skipped from review as they are similar to previous changes (19)
  • apps/dashboard/package.json
  • apps/dashboard/.env.example
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhooksAnalytics.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/layout.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/create-webhook-config-modal.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsServer.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/edit-webhook-config-modal.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/contracts/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-metrics.tsx
  • apps/dashboard/src/@/analytics/posthog-server.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/overview.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsFilter.tsx
  • apps/dashboard/src/@/api/analytics.ts
  • apps/dashboard/src/@/types/analytics.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/page.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-configs-table.tsx
  • apps/dashboard/src/@/api/webhook-configs.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/topic-selector-modal.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-config-modal.tsx
🧰 Additional context used
📓 Path-based instructions (2)
`**/*.{ts,tsx}`: Write idiomatic TypeScript with explicit function declarations ...

**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity
Re-use shared types from @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)

📄 Source: CodeRabbit Inference Engine (CLAUDE.md)

List of files the instruction was applied to:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx
`apps/{dashboard,playground-web}/**/*.{tsx,ts}`: Import UI primitives from `@/co...

apps/{dashboard,playground-web}/**/*.{tsx,ts}: Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Use NavLink for internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Use cn() from @/lib/utils for conditional class merging
Use design system tokens (e.g., bg-card, border-border, text-muted-foreground)
Expose className prop on root element for overrides in UI components
Server Components (Node edge): Start files with import "server-only";
Server Components: Read cookies/headers with next/headers
Server Components: Access server-only environment variables
Server Components: Perform heavy data fetching
Server Components: Implement redirect logic with redirect() from next/navigation
Client Components (browser): Begin files with 'use client';
Client Components: Handle interactive UI with React hooks (useState, useEffect, React Query, wallet hooks)
Client Components: Access browser APIs (localStorage, window, IntersectionObserver)
Client Components: Support fast transitions with prefetched data
Server Side Data Fetching: Always call getAuthToken() to retrieve JWT from cookies
Server Side Data Fetching: Use Authorization: Bearer header – never embed tokens in URLs
Server Side Data Fetching: Return typed results (Project[], User[]) – avoid any
Client Side Data Fetching: Wrap calls in React Query (@tanstack/react-query)
Client Side Data Fetching: Use descriptive, stable queryKeys for cache hits
Client Side Data Fetching: Configure staleTime/cacheTime based on freshness (default ≥ 60s)
Client Side Data Fetching: Keep tokens secret via internal API routes or server actions
Analytics Events: Never import posthog-js in server components

📄 Source: CodeRabbit Inference Engine (CLAUDE.md)

List of files the instruction was applied to:

  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Surface breaking changes prominently in PR descriptions
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Analytics Events: Never import `posthog-js` in server components
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/hooks/**/*.{ts,tsx} : Use React Query (`@tanstack/react-query`) for all client data fetching.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Heavy data fetching that should not ship to the client (e.g. analytics, billing).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Components: Perform heavy data fetching
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx (16)
Learnt from: jnsdls
PR: thirdweb-dev/js#6929
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx:14-19
Timestamp: 2025-05-21T05:17:31.283Z
Learning: In Next.js server components, the `params` object can sometimes be a Promise that needs to be awaited, despite type annotations suggesting otherwise. In apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/insight/webhooks/page.tsx, it's necessary to await the params object before accessing its properties.
Learnt from: arcoraven
PR: thirdweb-dev/js#7505
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx:186-204
Timestamp: 2025-07-10T10:18:33.238Z
Learning: The ThirdwebBarChart component in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx does not accept standard accessibility props like `aria-label` and `role` in its TypeScript interface, causing compilation errors when added.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Client Components: Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Anything that consumes hooks from `@tanstack/react-query` or thirdweb SDKs.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Components: Perform heavy data fetching
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Local state or effects live inside; data fetching happens in hooks.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : For notices & skeletons rely on `AnnouncementBanner`, `GenericLoadingPage`, `EmptyStateCard`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/**/*.{ts,tsx} : Keep components pure; fetch data outside (server component or hook) and pass it down via props.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/pages/*.client.tsx : Pages requiring fast transitions where data is prefetched on the client.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Server Components: Implement redirect logic with `redirect()` from `next/navigation`
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/api/**/*.{ts,tsx} : Redirect logic using `redirect()` from `next/navigation`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx,ts} : Use `NavLink` for internal navigation with automatic active states in dashboard and playground apps
Learnt from: MananTank
PR: thirdweb-dev/js#7434
File: apps/dashboard/src/app/(app)/team/~/~/contract/[chain]/[contractAddress]/components/project-selector.tsx:62-76
Timestamp: 2025-06-24T21:38:03.155Z
Learning: In the project-selector.tsx component for contract imports, the addToProject.mutate() call is intentionally not awaited (fire-and-forget pattern) to allow immediate navigation to the contract page while the import happens in the background. This is a deliberate design choice to prioritize user experience.
Learnt from: MananTank
PR: thirdweb-dev/js#7152
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx:41-48
Timestamp: 2025-05-26T16:28:50.772Z
Learning: The `projectMeta` prop is not required for the server-rendered `ContractTokensPage` component in the tokens shared page, unlike some other shared pages where it's needed for consistency.
Learnt from: MananTank
PR: thirdweb-dev/js#7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx:15-17
Timestamp: 2025-05-27T19:54:55.885Z
Learning: The `fetchDashboardContractMetadata` function from "@3rdweb-sdk/react/hooks/useDashboardContractMetadata" has internal error handlers for all promises and cannot throw errors, so external error handling is not needed when calling this function.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Size
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: Build Packages
  • GitHub Check: Unit Tests
  • GitHub Check: Lint Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx (2)

30-73: Excellent parallel data fetching implementation.

The implementation efficiently fetches webhook configurations, topics, and metrics in parallel, which optimizes performance. The error handling is appropriate, and the metrics map creation provides efficient lookup for the component.


16-19: Correct handling of potentially async params.

Good implementation following the Next.js pattern for handling params that may be a Promise in server components, as noted in the retrieved learnings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Dashboard Involves changes to the Dashboard. packages
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants