@@ -46,14 +46,25 @@ function UsersPage() {
4646 const [ updatingAdsUserId , setUpdatingAdsUserId ] = useState < string | null > (
4747 null
4848 )
49+ const [ emailFilter , setEmailFilter ] = useState ( '' )
4950
5051 const user = useConvexQuery ( api . auth . getCurrentUser )
52+ const pageSize = 10
5153 const usersQuery = useQuery ( {
5254 ...convexQuery ( api . users . listUsers , {
5355 pagination : {
54- limit : 10 ,
56+ limit : pageSize ,
5557 cursor : cursors [ currentPageIndex ] || null ,
5658 } ,
59+ emailFilter : emailFilter || undefined ,
60+ } ) ,
61+ placeholderData : keepPreviousData ,
62+ } )
63+ // Cast to any to avoid transient type mismatch until Convex codegen runs
64+ const countUsersRef : any = ( api as any ) . users ?. countUsers
65+ const countsQuery = useQuery ( {
66+ ...convexQuery ( countUsersRef , {
67+ emailFilter : emailFilter || undefined ,
5768 } ) ,
5869 placeholderData : keepPreviousData ,
5970 } )
@@ -353,6 +364,19 @@ function UsersPage() {
353364 < p className = "text-gray-600 dark:text-gray-400" >
354365 Manage user accounts and their capabilities.
355366 </ p >
367+ < div className = "mt-4" >
368+ < input
369+ type = "text"
370+ value = { emailFilter }
371+ onChange = { ( e ) => {
372+ setEmailFilter ( e . target . value )
373+ setCurrentPageIndex ( 0 )
374+ setCursors ( [ '' ] )
375+ } }
376+ placeholder = "Filter by email"
377+ className = "w-full max-w-md px-3 py-2 border rounded-md bg-white dark:bg-gray-900 border-gray-300 dark:border-gray-700 text-gray-900 dark:text-white"
378+ />
379+ </ div >
356380 </ div >
357381
358382 < div className = "bg-white dark:bg-gray-800 rounded-lg shadow-lg overflow-hidden" >
@@ -413,10 +437,22 @@ function UsersPage() {
413437 { /* Cursor-based pagination controls */ }
414438 < div className = "mt-6 flex items-center justify-between" >
415439 < div className = "text-sm text-gray-500 dark:text-gray-400" >
416- Page { currentPageIndex + 1 }
417- { usersQuery . data && (
418- < span > • { usersQuery . data . page ?. length } users</ span >
419- ) }
440+ { ( ( ) => {
441+ const filtered = countsQuery ?. data ?. filtered ?? 0
442+ const total = countsQuery ?. data ?. total ?? 0
443+ const totalPages = Math . max ( 1 , Math . ceil ( filtered / pageSize ) )
444+ const showing = usersQuery . data ?. page ?. length ?? 0
445+ return (
446+ < >
447+ Page { currentPageIndex + 1 } of { totalPages }
448+ < span >
449+ { ' ' }
450+ • showing { showing } of { filtered } users
451+ </ span >
452+ { emailFilter ? < span > (from { total } total)</ span > : null }
453+ </ >
454+ )
455+ } ) ( ) }
420456 </ div >
421457 < div className = "flex space-x-2" >
422458 < button
0 commit comments