Skip to content

Conversation

joaquim-verges
Copy link
Member

@joaquim-verges joaquim-verges commented Jul 9, 2025

<!--

## title your PR with this format: "[Dashboard] Feature: Advanced User Search for In-App Wallets"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

- Implemented an advanced search for in-app wallet users on the `[team]/[project]/wallets/users` page.
- Replaces the previous client-side filter with a server-side search using a new API endpoint.
- Users can now search by Email, Phone, ID, or Wallet Address via a dropdown and input field.
- Search results are displayed as individual user cards, replacing the main table.
- A "Clear Search" button allows returning to the full user list.
- The original "SearchInput" is retained for client-side filtering of the current page when no advanced search is active.

## How to test

1. Go to `apps/dashboard/[team]/[project]/wallets/users`.
2. Use the new "Advanced Search" bar:
    - Select a search type (Email, Phone, ID, Address).
    - Enter a query (e.g., an existing user's email).
    - Click "Search" or press Enter.
3. Verify search results display as cards.
4. Click "Clear Search & Return to List" and confirm the table reappears.
5. Test the old "Filter current page" input (when no advanced search results are active) to ensure it still filters the current page.
6. Test with a query that yields no results.

-->

Slack Thread


PR-Codex overview

This PR focuses on enhancing the user search functionality within the wallet management system. It introduces advanced search capabilities, improves user data retrieval, and refines the user interface for better usability.

Detailed summary

  • Added SearchType for search criteria.
  • Implemented AdvancedSearchInput for user search.
  • Integrated search results display with SearchResults.
  • Updated InAppWalletUsersPageContent to handle search actions.
  • Enhanced API calls to include ecosystemSlug and teamId.
  • Removed obsolete SearchInput component.

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

Summary by CodeRabbit

  • New Features

    • Introduced advanced user search with selectable criteria (email, phone, ID, or address) and enhanced search input.
    • Added a user-friendly results view displaying detailed user information and login methods.
    • Enabled clearing of search results to return to the full user list.
    • Added a "Users" tab in ecosystem navigation for easier access to user management.
    • Launched a dedicated ecosystem users page with integrated authentication and data fetching.
  • Enhancements

    • Improved state management for search results and loading indicators.
    • Retained simple search and table as fallback when no advanced search is active.
    • Expanded support for ecosystem identifiers alongside client IDs in wallet data fetching.

@joaquim-verges joaquim-verges requested review from a team as code owners July 9, 2025 08:34
Copy link

changeset-bot bot commented Jul 9, 2025

⚠️ No Changeset found

Latest commit: 936aa84

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

vercel bot commented Jul 9, 2025

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

Name Status Preview Comments Updated (UTC)
thirdweb-www ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 10, 2025 10:09am
4 Skipped Deployments
Name Status Preview Comments Updated (UTC)
docs-v2 ⬜️ Skipped (Inspect) Jul 10, 2025 10:09am
nebula ⬜️ Skipped (Inspect) Jul 10, 2025 10:09am
thirdweb_playground ⬜️ Skipped (Inspect) Jul 10, 2025 10:09am
wallet-ui ⬜️ Skipped (Inspect) Jul 10, 2025 10:09am

Copy link
Contributor

coderabbitai bot commented Jul 9, 2025

Walkthrough

The changes introduce an advanced user search feature to the dashboard's wallet users page. New React components and TypeScript types are added to support advanced search input, search results display, and API interaction. The main page component is updated to integrate these features, manage search state, and conditionally render results or the original table. Additionally, hooks and API calls are enhanced to support ecosystem slug parameters, and navigation is extended with a new "Users" tab in the ecosystem layout.

Changes

File(s) Change Summary
.../AdvancedSearchInput.tsx Added AdvancedSearchInput React component for selecting search type and entering queries, with loading, clear, and search actions.
.../SearchResults.tsx Added SearchResults React component to display user search results in structured cards with badges and tooltips.
.../index.tsx Enhanced main page component to support advanced search: added state for results/loading, integrated new input/results components, updated UI logic for conditional rendering, and updated props to accept either projectClientId or ecosystemSlug.
.../searchUsers.ts Added async function searchUsers to query remote API for user search by type and query, returning results or throwing errors.
.../types.ts Added SearchType type alias defining allowed search criteria strings: `"email"
.../@/hooks/useEmbeddedWallets.ts Updated hooks and fetch functions to optionally accept ecosystemSlug alongside clientId, adjusting query parameters, headers, and query keys accordingly.
.../EcosystemSlugLayout.tsx Added a new "Users" tab link to the ecosystem layout navigation tabs.
.../users/page.tsx Added new EcosystemUsersPage async React server component that fetches auth token, ecosystem, and team data, redirects if necessary, and renders the wallet users page content with ecosystem slug support.
.../users/page.tsx (project) Passed teamId prop to InAppWalletUsersPageContent component from project data.
.../SearchInput.tsx Removed deprecated SearchInput component replaced by AdvancedSearchInput.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant AdvancedSearchInput
    participant InAppWalletUsersPageContent
    participant searchUsers (API)
    participant SearchResults

    User->>AdvancedSearchInput: Selects search type, enters query, clicks Search
    AdvancedSearchInput->>InAppWalletUsersPageContent: onSearch(searchType, query)
    InAppWalletUsersPageContent->>searchUsers (API): searchUsers(authToken, clientId/ecosystemSlug, searchType, query)
    searchUsers (API)-->>InAppWalletUsersPageContent: Returns WalletUser[]
    InAppWalletUsersPageContent->>SearchResults: Passes results for display
    User->>AdvancedSearchInput: Clicks "Clear Search & Return to List"
    AdvancedSearchInput->>InAppWalletUsersPageContent: onClear()
    InAppWalletUsersPageContent->>SearchResults: Clears results, returns to list
Loading

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • TEAM-0000: Entity not found: Issue - Could not find referenced Issue.

📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 936aa84 and 5afb0b0.

📒 Files selected for processing (3)
  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts (4 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/SearchInput.tsx (0 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/searchUsers.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/SearchInput.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/searchUsers.ts
  • apps/dashboard/src/@/hooks/useEmbeddedWallets.ts
⏰ 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: E2E Tests (pnpm, vite)
  • GitHub Check: Size
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: Unit Tests
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: Build Packages
  • GitHub Check: Lint Packages
  • GitHub Check: Analyze (javascript)
✨ 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.

Copy link
Contributor

graphite-app bot commented Jul 9, 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.

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

codecov bot commented Jul 9, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 56.50%. Comparing base (2111b8b) to head (5afb0b0).
Report is 11 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7572      +/-   ##
==========================================
- Coverage   56.51%   56.50%   -0.02%     
==========================================
  Files         906      906              
  Lines       57992    58047      +55     
  Branches     4223     4227       +4     
==========================================
+ Hits        32777    32797      +20     
- Misses      25107    25140      +33     
- Partials      108      110       +2     
Flag Coverage Δ
packages 56.50% <ø> (-0.02%) ⬇️

see 21 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 9, 2025

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
thirdweb (esm) 63.17 KB (0%) 1.3 s (0%) 269 ms (+98.07% 🔺) 1.6 s
thirdweb (cjs) 353.22 KB (0%) 7.1 s (0%) 958 ms (-2.24% 🔽) 8.1 s
thirdweb (minimal + tree-shaking) 5.69 KB (0%) 114 ms (0%) 131 ms (+1946.55% 🔺) 244 ms
thirdweb/chains (tree-shaking) 526 B (0%) 11 ms (0%) 42 ms (+808.46% 🔺) 53 ms
thirdweb/react (minimal + tree-shaking) 19.58 KB (0%) 392 ms (0%) 80 ms (+327.97% 🔺) 471 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: 8

🧹 Nitpick comments (7)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/searchUsers.ts (1)

1-1: Consider importing SearchParams type for consistency.

The file imports SearchParams from ./types but doesn't use it. Consider either removing the unused import or using it for parameter validation.

-import type { SearchParams, SearchType, UserSearchResult } from "./types";
+import type { SearchType, UserSearchResult } from "./types";
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/types.ts (1)

1-17: Consider adding JSDoc comments for better documentation.

The interface structure is well-defined, but consider adding JSDoc comments to document the purpose and expected values of each field.

+/**
+ * Represents a user search result from the in-app wallet API
+ */
 export interface UserSearchResult {
+  /** Unique identifier for the user */
   userId: string;
+  /** Primary wallet address associated with the user */
   walletAddress: string;
+  /** Optional email address */
   email?: string;
+  /** Optional phone number */
   phone?: string;
+  /** ISO timestamp of when the user was created */
   createdAt: string;
+  /** Array of linked authentication accounts */
   linkedAccounts: {
+    /** Type of authentication method (e.g., "email", "phone", "google") */
     type: string;
+    /** Additional details specific to the authentication method */
     details: {
       phone?: string;
       email?: string;
       address?: string;
       id?: string;
       [key: string]: unknown;
     };
   }[];
 }
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/SearchResults.tsx (2)

16-18: Consider improving the user identifier prioritization logic.

The current prioritization (email > phone > walletAddress > userId) might not always provide the most user-friendly identifier. Consider the context of the search type to prioritize accordingly.

-const getUserIdentifier = (user: UserSearchResult) => {
-  return user.email ?? user.phone ?? user.walletAddress ?? user.userId;
-};
+const getUserIdentifier = (user: UserSearchResult, searchType?: SearchType) => {
+  // If we searched by a specific type, prioritize that field
+  if (searchType === "email" && user.email) return user.email;
+  if (searchType === "phone" && user.phone) return user.phone;
+  if (searchType === "walletAddress" && user.walletAddress) return user.walletAddress;
+  
+  // Fallback to default prioritization
+  return user.email ?? user.phone ?? user.walletAddress ?? user.userId;
+};

97-121: Consider optimizing tooltip rendering for performance.

Creating a new TooltipProvider for each badge could impact performance with many search results. Consider moving the provider to a higher level.

               <div className="flex flex-wrap gap-1">
+                <TooltipProvider>
                   {user.linkedAccounts.map((account, index) => (
-                    <TooltipProvider
-                      key={`${user.userId}-${account.type}-${index}`}
-                    >
-                      <Tooltip>
+                      <Tooltip key={`${user.userId}-${account.type}-${index}`}>
                         <TooltipTrigger>
                           <Badge variant="secondary" className="text-xs">
                             {account.type}
                           </Badge>
                         </TooltipTrigger>
                         <TooltipContent>
                           <div className="text-sm space-y-1">
                             {Object.entries(account.details).map(
                               ([key, value]) => (
                                 <div key={key}>
                                   <span className="font-medium">{key}:</span>{" "}
                                   {String(value)}
                                 </div>
                               ),
                             )}
                           </div>
                         </TooltipContent>
                       </Tooltip>
-                    </TooltipProvider>
                   ))}
+                </TooltipProvider>
               </div>
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/AdvancedSearchInput.tsx (2)

26-30: Consider adding input validation based on search type.

The current implementation doesn't validate the input format. Consider adding validation for email and phone formats.

   const handleSearch = () => {
-    if (query.trim()) {
-      props.onSearch(searchType, query.trim());
-    }
+    const trimmedQuery = query.trim();
+    if (!trimmedQuery) return;
+    
+    // Basic validation based on search type
+    if (searchType === "email" && !trimmedQuery.includes("@")) {
+      // Could add proper email validation here
+      return;
+    }
+    
+    props.onSearch(searchType, trimmedQuery);
   };

3-14: Consider adding debouncing for better UX.

For better user experience, consider implementing debouncing to avoid triggering searches on every keystroke when using Enter key.

You could use a debounced version of the search function:

 import { SearchIcon } from "lucide-react";
-import { useState } from "react";
+import { useState, useCallback } from "react";
+import { useDebounce } from "@/hooks/useDebounce"; // if available

Then implement debouncing in the component logic.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/index.tsx (1)

118-120: Consider simplifying search state management.

The current state management uses separate boolean flags which could be simplified. Consider using a single state object or enum for better maintainability.

-  const [searchResults, setSearchResults] = useState<UserSearchResult[]>([]);
-  const [isSearching, setIsSearching] = useState(false);
-  const [hasSearchResults, setHasSearchResults] = useState(false);
+  const [searchState, setSearchState] = useState<{
+    results: UserSearchResult[];
+    isLoading: boolean;
+    hasSearched: boolean;
+  }>({
+    results: [],
+    isLoading: false,
+    hasSearched: false,
+  });
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2111b8b and fc36f27.

📒 Files selected for processing (5)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/AdvancedSearchInput.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/SearchResults.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/index.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/searchUsers.ts (1 hunks)
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/types.ts (1 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/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/searchUsers.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/AdvancedSearchInput.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/index.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/types.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/SearchResults.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)/wallets/users/components/searchUsers.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/AdvancedSearchInput.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/index.tsx
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/types.ts
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/SearchResults.tsx
🧠 Learnings (6)
📓 Common learnings
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: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to src/wallets/**/*.{ts,tsx} : Support for in-app wallets (social/email login) in wallet architecture
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 src/wallets/**/*.{ts,tsx} : Unified `Wallet` and `Account` interfaces in wallet architecture
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} : Support EIP-1193, EIP-5792, EIP-7702 standards in wallet architecture
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: Perform heavy data fetching
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/searchUsers.ts (10)
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} : Support for in-app wallets (social/email login) 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`.
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 src/wallets/**/*.{ts,tsx} : Smart wallets with account abstraction 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: 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} : 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/**/api/**/*.{ts,tsx} : Always call `getAuthToken()` to get the JWT from cookies.
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: Always call `getAuthToken()` to retrieve JWT from cookies
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)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/AdvancedSearchInput.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: 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} : 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.489Z
Learning: Applies to src/wallets/**/*.{ts,tsx} : Support for in-app wallets (social/email login) in wallet architecture
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 : 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: .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.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/*.client.tsx : When you need access to browser APIs (localStorage, window, IntersectionObserver etc.).
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 : Client components must start with `'use client';` before imports.
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';`
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/index.tsx (15)
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} : Support for in-app wallets (social/email login) in wallet architecture
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: 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 src/wallets/**/*.{ts,tsx} : Smart wallets with account abstraction 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 src/wallets/**/*.{ts,tsx} : Support EIP-1193, EIP-5792, EIP-7702 standards in wallet architecture
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: 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: 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.488Z
Learning: Applies to test/src/test-wallets.ts : Predefined test accounts are in `test/src/test-wallets.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 : 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/**/pages/*.client.tsx : Pages requiring fast transitions where data is prefetched on the client.
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: jnsdls
PR: thirdweb-dev/js#7188
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx:15-15
Timestamp: 2025-05-29T00:46:09.063Z
Learning: In the accounts component at apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx, the 3-column grid layout (md:grid-cols-3) is intentionally maintained even when rendering only one StatCard, as part of the design structure for this component.
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/types.ts (10)
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 src/wallets/**/*.{ts,tsx} : Support for in-app wallets (social/email login) 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 src/wallets/**/*.{ts,tsx} : Smart wallets with account abstraction 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 src/wallets/**/*.{ts,tsx} : Support EIP-1193, EIP-5792, EIP-7702 standards in wallet architecture
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.488Z
Learning: Applies to test/src/test-wallets.ts : Predefined test accounts are in `test/src/test-wallets.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/**/api/**/*.{ts,tsx} : Return typed results (`Project[]`, `User[]`, …) – avoid `any`.
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/**/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: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to src/extensions/**/*.{ts,tsx} : Auto-generated contracts from ABI definitions in extensions
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/SearchResults.tsx (14)
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: CLAUDE.md:0-0
Timestamp: 2025-06-30T10:25:29.489Z
Learning: Applies to src/wallets/**/*.{ts,tsx} : Support for in-app wallets (social/email login) 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/**/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/**/api/**/*.{ts,tsx} : Return typed results (`Project[]`, `User[]`, …) – avoid `any`.
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: .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}/**/*.{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: MananTank
PR: thirdweb-dev/js#7227
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/OpenEditionMetadata.tsx:26-26
Timestamp: 2025-05-30T17:14:25.332Z
Learning: The ModuleCardUIProps interface already includes a client prop of type ThirdwebClient, so when components use `Omit<ModuleCardUIProps, "children" | "updateButton">`, they inherit the client prop without needing to add it explicitly.
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: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-06-30T10:26:04.389Z
Learning: Applies to dashboard/**/components/*.client.tsx : Client components must start with `'use client';` before imports.
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';`
🧬 Code Graph Analysis (3)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/searchUsers.ts (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/types.ts (2)
  • SearchType (19-19)
  • UserSearchResult (1-17)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/AdvancedSearchInput.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/types.ts (1)
  • SearchType (19-19)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/SearchResults.tsx (1)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/types.ts (1)
  • UserSearchResult (1-17)
⏰ 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: E2E Tests (pnpm, esbuild)
  • GitHub Check: Unit Tests
  • GitHub Check: Size
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: Build Packages
  • GitHub Check: Lint Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (5)
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/SearchResults.tsx (1)

1-1: LGTM - Proper client component declaration.

The component correctly starts with "use client" directive as required for interactive components.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/AdvancedSearchInput.tsx (1)

1-1: LGTM - Proper client component declaration.

The component correctly starts with "use client" directive as required for interactive components.

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/index.tsx (3)

25-28: LGTM - Proper imports for new search functionality.

The new imports are correctly added and follow the established patterns in the codebase.


247-249: LGTM - Clean conditional rendering logic.

The conditional rendering between search results and the original table is well-structured and maintains good user experience.


213-219: SearchType "address" is used consistently and correctly mapped to the API parameter

The SearchType includes "address", the AdvancedSearchInput SelectItem uses value="address", and in searchUsers.ts you intentionally map "address""walletAddress" for the query parameter. Everything aligns—no changes needed.

Comment on lines 38 to 39
const data = await response.json();
return data as UserSearchResult[];
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding runtime validation for API response.

The type assertion as UserSearchResult[] assumes the API returns the expected structure. Consider adding runtime validation to ensure data integrity.

   const data = await response.json();
-  return data as UserSearchResult[];
+  
+  // Basic runtime validation
+  if (!Array.isArray(data)) {
+    throw new Error("Invalid response format: expected array");
+  }
+  
+  return data as UserSearchResult[];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const data = await response.json();
return data as UserSearchResult[];
const data = await response.json();
// Basic runtime validation
if (!Array.isArray(data)) {
throw new Error("Invalid response format: expected array");
}
return data as UserSearchResult[];
🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/searchUsers.ts
around lines 38 to 39, the code uses a type assertion to cast the API response
to UserSearchResult[] without verifying the data structure. To fix this, add
runtime validation after parsing the JSON to check that the data matches the
expected UserSearchResult[] format, such as verifying required fields and types,
before returning it. This ensures data integrity and prevents runtime errors
from unexpected API responses.

Comment on lines 3 to 7
export async function searchUsers(
authToken: string,
searchType: SearchType,
query: string,
): Promise<UserSearchResult[]> {
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add input parameter validation.

The function doesn't validate input parameters. Consider adding validation to ensure authToken is not empty and query is not just whitespace.

 export async function searchUsers(
   authToken: string,
   searchType: SearchType,
   query: string,
 ): Promise<UserSearchResult[]> {
+  if (!authToken.trim()) {
+    throw new Error("Authentication token is required");
+  }
+  if (!query.trim()) {
+    throw new Error("Search query cannot be empty");
+  }
+
   const url = new URL(
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export async function searchUsers(
authToken: string,
searchType: SearchType,
query: string,
): Promise<UserSearchResult[]> {
export async function searchUsers(
authToken: string,
searchType: SearchType,
query: string,
): Promise<UserSearchResult[]> {
if (!authToken.trim()) {
throw new Error("Authentication token is required");
}
if (!query.trim()) {
throw new Error("Search query cannot be empty");
}
const url = new URL(
// …rest of URL construction
);
// …rest of implementation
}
🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/searchUsers.ts
around lines 3 to 7, the searchUsers function lacks validation for its input
parameters. Add checks to ensure authToken is not empty or null and that query
is not just whitespace. If validation fails, throw an appropriate error or
handle it gracefully to prevent invalid inputs from proceeding.

Comment on lines 19 to 27
export type SearchType = "email" | "phone" | "id" | "address";

export interface SearchParams {
queryBy: SearchType | "walletAddress";
email?: string;
phone?: string;
id?: string;
walletAddress?: string;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix type inconsistency between SearchType and SearchParams.

There's an inconsistency where SearchType defines "address" but SearchParams uses "walletAddress". This mismatch could lead to runtime errors.

-export type SearchType = "email" | "phone" | "id" | "address";
+export type SearchType = "email" | "phone" | "id" | "walletAddress";

 export interface SearchParams {
-  queryBy: SearchType | "walletAddress";
+  queryBy: SearchType;
   email?: string;
   phone?: string;
   id?: string;
   walletAddress?: string;
 }

Alternatively, if you want to keep "address" as the display name, update the SearchParams accordingly:

 export interface SearchParams {
-  queryBy: SearchType | "walletAddress";
+  queryBy: SearchType;
   email?: string;
   phone?: string;
   id?: string;
-  walletAddress?: string;
+  address?: string;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export type SearchType = "email" | "phone" | "id" | "address";
export interface SearchParams {
queryBy: SearchType | "walletAddress";
email?: string;
phone?: string;
id?: string;
walletAddress?: string;
}
export type SearchType = "email" | "phone" | "id" | "walletAddress";
export interface SearchParams {
queryBy: SearchType;
email?: string;
phone?: string;
id?: string;
walletAddress?: string;
}
🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/types.ts
between lines 19 and 27, there is a type inconsistency where SearchType includes
"address" but SearchParams uses "walletAddress". To fix this, either change
"address" in SearchType to "walletAddress" to match SearchParams or update
SearchParams to use "address" instead of "walletAddress" so both types align and
prevent runtime errors.

Comment on lines 109 to 116
{Object.entries(account.details).map(
([key, value]) => (
<div key={key}>
<span className="font-medium">{key}:</span>{" "}
{String(value)}
</div>
),
)}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add safety check for account details rendering.

The code assumes account.details exists and contains valid data. Consider adding safety checks to prevent rendering errors.

                         <TooltipContent>
                           <div className="text-sm space-y-1">
-                            {Object.entries(account.details).map(
+                            {Object.entries(account.details || {}).map(
                               ([key, value]) => (
-                                <div key={key}>
-                                  <span className="font-medium">{key}:</span>{" "}
-                                  {String(value)}
-                                </div>
+                                value !== undefined && value !== null && (
+                                  <div key={key}>
+                                    <span className="font-medium">{key}:</span>{" "}
+                                    {String(value)}
+                                  </div>
+                                )
                               ),
                             )}
                           </div>
🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/SearchResults.tsx
around lines 109 to 116, the code assumes account.details always exists and is
iterable, which can cause runtime errors if it is undefined or null. Add a
safety check before mapping over account.details, such as verifying it is an
object or has entries, to prevent rendering errors when account.details is
missing or invalid.

<div className="flex gap-2">
<Select
value={searchType}
onValueChange={(value) => setSearchType(value as SearchType)}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix type safety issue in search type casting.

The type casting value as SearchType is not type-safe. The Select component should already ensure the value is valid, but consider adding runtime validation.

-          onValueChange={(value) => setSearchType(value as SearchType)}
+          onValueChange={(value) => {
+            if (value === "email" || value === "phone" || value === "id" || value === "address") {
+              setSearchType(value);
+            }
+          }}
🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/AdvancedSearchInput.tsx
at line 48, the current type casting of value to SearchType is unsafe. Replace
the direct cast with a runtime check to confirm the value is a valid SearchType
before calling setSearchType. This can be done by verifying the value against
the allowed SearchType values and only setting the state if valid, otherwise
handle the invalid case appropriately.

Comment on lines 172 to 176
const handleClearSearch = () => {
setSearchResults([]);
setHasSearchResults(false);
setSearchValue("");
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding input validation to handleSearch.

The function doesn't validate the input parameters before making the API call.

   const handleSearch = async (searchType: SearchType, query: string) => {
+    if (!query.trim()) {
+      return;
+    }
+    
     setIsSearching(true);
     try {
       const results = await searchUsers(props.authToken, searchType, query);

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/index.tsx
around lines 172 to 176, the handleSearch function lacks input validation before
making the API call. Add validation logic to check if the search input is valid
(e.g., non-empty, correct format) before proceeding with the API request. If the
input is invalid, avoid making the API call and optionally provide user feedback
or clear previous results.

Comment on lines 157 to 170
const handleSearch = async (searchType: SearchType, query: string) => {
setIsSearching(true);
try {
const results = await searchUsers(props.authToken, searchType, query);
setSearchResults(results);
setHasSearchResults(true);
} catch (error) {
console.error("Search failed:", error);
setSearchResults([]);
setHasSearchResults(true);
} finally {
setIsSearching(false);
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve error handling with user feedback.

The current error handling only logs to console. Users should receive feedback when searches fail.

   const handleSearch = async (searchType: SearchType, query: string) => {
     setIsSearching(true);
     try {
       const results = await searchUsers(props.authToken, searchType, query);
       setSearchResults(results);
       setHasSearchResults(true);
     } catch (error) {
       console.error("Search failed:", error);
-      setSearchResults([]);
-      setHasSearchResults(true);
+      // Show user-friendly error message
+      setSearchResults([]);
+      setHasSearchResults(true);
+      // Consider using a toast notification or error state
+      // toast.error("Search failed. Please try again.");
     } finally {
       setIsSearching(false);
     }
   };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleSearch = async (searchType: SearchType, query: string) => {
setIsSearching(true);
try {
const results = await searchUsers(props.authToken, searchType, query);
setSearchResults(results);
setHasSearchResults(true);
} catch (error) {
console.error("Search failed:", error);
setSearchResults([]);
setHasSearchResults(true);
} finally {
setIsSearching(false);
}
};
const handleSearch = async (searchType: SearchType, query: string) => {
setIsSearching(true);
try {
const results = await searchUsers(props.authToken, searchType, query);
setSearchResults(results);
setHasSearchResults(true);
} catch (error) {
console.error("Search failed:", error);
// Show user-friendly error message
setSearchResults([]);
setHasSearchResults(true);
// Consider using a toast notification or error state
// toast.error("Search failed. Please try again.");
} finally {
setIsSearching(false);
}
};
🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/index.tsx
around lines 157 to 170, the error handling in handleSearch only logs errors to
the console without informing users. Modify the catch block to set an error
state or message that can be displayed in the UI, providing clear feedback to
users when a search fails, while keeping the existing state resets and logging.

@vercel vercel bot temporarily deployed to Preview – thirdweb_playground July 10, 2025 02:40 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 July 10, 2025 02:40 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula July 10, 2025 02:40 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui July 10, 2025 02:40 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground July 10, 2025 03:17 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui July 10, 2025 03:17 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula July 10, 2025 03:17 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 July 10, 2025 03:17 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui July 10, 2025 04:23 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 July 10, 2025 04:23 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula July 10, 2025 04:23 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground July 10, 2025 04:23 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui July 10, 2025 08:06 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground July 10, 2025 08:06 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 July 10, 2025 08:06 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 July 10, 2025 08:26 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula July 10, 2025 08:26 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui July 10, 2025 08:26 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground July 10, 2025 08:26 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula July 10, 2025 09:31 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui July 10, 2025 09:31 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground July 10, 2025 09:31 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 July 10, 2025 09:31 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui July 10, 2025 09:50 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 July 10, 2025 09:50 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground July 10, 2025 09:50 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula July 10, 2025 09:50 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground July 10, 2025 10:01 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui July 10, 2025 10:01 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula July 10, 2025 10:01 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 July 10, 2025 10:01 Inactive
@joaquim-verges joaquim-verges merged commit 91e3781 into main Jul 10, 2025
24 checks passed
@joaquim-verges joaquim-verges deleted the cursor/improve-user-filtering-functionality-9b6c branch July 10, 2025 18:53
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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants