-
Notifications
You must be signed in to change notification settings - Fork 589
[Dashboard] Improve user filtering functionality #7572
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
[Dashboard] Improve user filtering functionality #7572
Conversation
Co-authored-by: joaquim.verges <[email protected]>
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
WalkthroughThe 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
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
Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (3)
💤 Files with no reviewable changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
⏰ 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)
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
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. |
Codecov ReportAll modified and coverable lines are covered by tests ✅
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
🚀 New features to boost your workflow:
|
size-limit report 📦
|
There was a problem hiding this 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 availableThen 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
📒 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 localtypes.ts
barrels
Prefer type aliases over interface except for nominal shapes
Avoidany
andunknown
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
UseNavLink
for internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Usecn()
from@/lib/utils
for conditional class merging
Use design system tokens (e.g.,bg-card
,border-border
,text-muted-foreground
)
ExposeclassName
prop on root element for overrides in UI components
Server Components (Node edge): Start files withimport "server-only";
Server Components: Read cookies/headers withnext/headers
Server Components: Access server-only environment variables
Server Components: Perform heavy data fetching
Server Components: Implement redirect logic withredirect()
fromnext/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 callgetAuthToken()
to retrieve JWT from cookies
Server Side Data Fetching: UseAuthorization: Bearer
header – never embed tokens in URLs
Server Side Data Fetching: Return typed results (Project[]
,User[]
) – avoidany
Client Side Data Fetching: Wrap calls in React Query (@tanstack/react-query
)
Client Side Data Fetching: Use descriptive, stablequeryKeys
for cache hits
Client Side Data Fetching: ConfigurestaleTime
/cacheTime
based on freshness (default ≥ 60s)
Client Side Data Fetching: Keep tokens secret via internal API routes or server actions
Analytics Events: Never importposthog-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 parameterThe
SearchType
includes"address"
, theAdvancedSearchInput
SelectItem usesvalue="address"
, and insearchUsers.ts
you intentionally map"address"
→"walletAddress"
for the query parameter. Everything aligns—no changes needed.
const data = await response.json(); | ||
return data as UserSearchResult[]; |
There was a problem hiding this comment.
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.
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.
.../app/(app)/team/[team_slug]/[project_slug]/(sidebar)/wallets/users/components/searchUsers.ts
Outdated
Show resolved
Hide resolved
export async function searchUsers( | ||
authToken: string, | ||
searchType: SearchType, | ||
query: string, | ||
): Promise<UserSearchResult[]> { |
There was a problem hiding this comment.
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.
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.
export type SearchType = "email" | "phone" | "id" | "address"; | ||
|
||
export interface SearchParams { | ||
queryBy: SearchType | "walletAddress"; | ||
email?: string; | ||
phone?: string; | ||
id?: string; | ||
walletAddress?: string; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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.
{Object.entries(account.details).map( | ||
([key, value]) => ( | ||
<div key={key}> | ||
<span className="font-medium">{key}:</span>{" "} | ||
{String(value)} | ||
</div> | ||
), | ||
)} |
There was a problem hiding this comment.
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)} |
There was a problem hiding this comment.
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.
const handleClearSearch = () => { | ||
setSearchResults([]); | ||
setHasSearchResults(false); | ||
setSearchValue(""); | ||
}; |
There was a problem hiding this comment.
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.
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); | ||
} | ||
}; |
There was a problem hiding this comment.
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.
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.
Co-authored-by: joaquim.verges <[email protected]>
Co-authored-by: joaquim.verges <[email protected]>
Co-authored-by: joaquim.verges <[email protected]>
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
SearchType
for search criteria.AdvancedSearchInput
for user search.SearchResults
.InAppWalletUsersPageContent
to handle search actions.ecosystemSlug
andteamId
.SearchInput
component.Summary by CodeRabbit
New Features
Enhancements