@@ -26,7 +26,12 @@ const UserManagement = () => {
2626 const updateUserRole = useUpdateUserRole ( ) ;
2727 const bulkAssign = useBulkAssignDevices ( ) ;
2828 const bulkUnassign = useBulkUnassignDevices ( ) ;
29+ const removeUser = useDeleteUser ( ) ;
2930
31+ // User Filtering State
32+ const [ userSearch , setUserSearch ] = useState ( "" ) ;
33+ const [ roleFilter , setRoleFilter ] = useState < 'all' | 'viewer' | 'editor' > ( 'all' ) ;
34+
3035 // New User Form State
3136 const [ email , setEmail ] = useState ( "" ) ;
3237 const [ password , setPassword ] = useState ( "" ) ;
@@ -37,6 +42,12 @@ const UserManagement = () => {
3742
3843 const isBulkOperating = bulkAssign . isPending || bulkUnassign . isPending ;
3944
45+ const filteredUsers = users . filter ( user => {
46+ const matchesSearch = user . email . toLowerCase ( ) . includes ( userSearch . toLowerCase ( ) ) ;
47+ const matchesRole = roleFilter === 'all' || user . role === roleFilter ;
48+ return matchesSearch && matchesRole ;
49+ } ) ;
50+
4051 const filteredDevices = allDevices . filter ( d =>
4152 d . title . toLowerCase ( ) . includes ( deviceSearch . toLowerCase ( ) ) ||
4253 d . id . toLowerCase ( ) . includes ( deviceSearch . toLowerCase ( ) )
@@ -170,9 +181,35 @@ const UserManagement = () => {
170181 { /* ── Users List & Access Control ── */ }
171182 < Card className = "lg:col-span-2" >
172183 < CardHeader >
173- < CardTitle className = "flex items-center gap-2" >
174- < Users className = "h-5 w-5" />
175- User Directory & Access
184+ < CardTitle className = "flex items-center justify-between gap-2" >
185+ < div className = "flex items-center gap-2" >
186+ < Users className = "h-5 w-5" />
187+ User Directory & Access
188+ </ div >
189+ < div className = "flex items-center gap-2" >
190+ < div className = "relative" >
191+ < Search className = "absolute left-2 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" />
192+ < Input
193+ placeholder = "Search users..."
194+ className = "h-8 pl-8 text-xs w-[150px] lg:w-[200px]"
195+ value = { userSearch }
196+ onChange = { ( e ) => setUserSearch ( e . target . value ) }
197+ />
198+ </ div >
199+ < Select
200+ value = { roleFilter }
201+ onValueChange = { ( val : 'all' | 'viewer' | 'editor' ) => setRoleFilter ( val ) }
202+ >
203+ < SelectTrigger className = "h-8 w-[110px] text-xs" >
204+ < SelectValue placeholder = "Role" />
205+ </ SelectTrigger >
206+ < SelectContent >
207+ < SelectItem value = "all" > All Roles</ SelectItem >
208+ < SelectItem value = "viewer" > Viewer</ SelectItem >
209+ < SelectItem value = "editor" > Editor</ SelectItem >
210+ </ SelectContent >
211+ </ Select >
212+ </ div >
176213 </ CardTitle >
177214 < CardDescription >
178215 Assign specific devices to allow non-admin users to view them.
@@ -183,13 +220,17 @@ const UserManagement = () => {
183220 < div className = "flex justify-center p-8" >
184221 < Loader2 className = "h-8 w-8 animate-spin text-muted-foreground" />
185222 </ div >
186- ) : users . length === 0 ? (
223+ ) : filteredUsers . length === 0 ? (
187224 < div className = "text-center p-8 border rounded-lg bg-muted/20" >
188- < p className = "text-muted-foreground" > No users found.</ p >
225+ < p className = "text-muted-foreground" >
226+ { userSearch || roleFilter !== 'all'
227+ ? "No users found matching the criteria."
228+ : "No users found." }
229+ </ p >
189230 </ div >
190231 ) : (
191232 < div className = "space-y-4" >
192- { users . map ( ( user ) => (
233+ { filteredUsers . map ( ( user ) => (
193234 < div key = { user . id } className = "border rounded-lg p-4 bg-card shadow-sm" >
194235 < div className = "flex items-start justify-between mb-4" >
195236 < div >
0 commit comments