@@ -2,7 +2,7 @@ import Button from "@components/Button";
22import { notify } from "@components/Notification" ;
33import { useApiCall } from "@utils/api" ;
44import { isNetBirdHosted } from "@utils/netbird" ;
5- import { Trash2 } from "lucide-react" ;
5+ import { CheckCircle , Trash2 , XCircle } from "lucide-react" ;
66import * as React from "react" ;
77import { useMemo } from "react" ;
88import { useSWRConfig } from "swr" ;
@@ -36,6 +36,40 @@ export default function UserActionCell({
3636 } ) ;
3737 } ;
3838
39+ const approveUser = async ( ) => {
40+ const name = user . name || "User" ;
41+ notify ( {
42+ title : `'${ name } ' approved` ,
43+ description : "User was successfully approved." ,
44+ promise : userRequest . post ( "" , `/${ user . id } /approve` ) . then ( ( ) => {
45+ mutate ( `/users?service_user=${ serviceUser } ` ) ;
46+ } ) ,
47+ loadingMessage : "Approving the user..." ,
48+ } ) ;
49+ } ;
50+
51+ const rejectUser = async ( ) => {
52+ const name = user . name || "User" ;
53+ const choice = await confirm ( {
54+ title : `Reject '${ name } '?` ,
55+ description :
56+ "Rejecting this user will remove them from the account permanently. This action cannot be undone." ,
57+ confirmText : "Reject" ,
58+ cancelText : "Cancel" ,
59+ type : "danger" ,
60+ } ) ;
61+ if ( ! choice ) return ;
62+
63+ notify ( {
64+ title : `'${ name } ' rejected` ,
65+ description : "User was successfully rejected and removed." ,
66+ promise : userRequest . del ( "" , `/${ user . id } /reject` ) . then ( ( ) => {
67+ mutate ( `/users?service_user=${ serviceUser } ` ) ;
68+ } ) ,
69+ loadingMessage : "Rejecting the user..." ,
70+ } ) ;
71+ } ;
72+
3973 const openConfirm = async ( ) => {
4074 const name = user . name || "User" ;
4175 const choice = await confirm ( {
@@ -55,21 +89,50 @@ export default function UserActionCell({
5589 return user . is_current ;
5690 } , [ permission . users . delete , user . is_current ] ) ;
5791
92+ const isPendingApproval = user . pending_approval ;
93+ const canManageUsers = permission . users . update ;
94+
5895 return (
59- < div className = { "flex justify-end pr-4 items-center gap-4 " } >
60- { ! serviceUser && isNetBirdHosted ( ) && (
96+ < div className = { "flex justify-end pr-4 items-center gap-2 " } >
97+ { ! serviceUser && isNetBirdHosted ( ) && ! isPendingApproval && (
6198 < UserResendInviteButton user = { user } />
6299 ) }
63- < Button
64- variant = { "danger-outline" }
65- size = { "sm" }
66- onClick = { openConfirm }
67- data-cy = { "delete-user" }
68- disabled = { disabled }
69- >
70- < Trash2 size = { 16 } />
71- Delete
72- </ Button >
100+
101+ { isPendingApproval && canManageUsers && (
102+ < >
103+ < Button
104+ variant = { "outline" }
105+ size = { "sm" }
106+ onClick = { approveUser }
107+ data-cy = { "approve-user" }
108+ >
109+ < CheckCircle size = { 16 } />
110+ Approve
111+ </ Button >
112+ < Button
113+ variant = { "danger-outline" }
114+ size = { "sm" }
115+ onClick = { rejectUser }
116+ data-cy = { "reject-user" }
117+ >
118+ < XCircle size = { 16 } />
119+ Reject
120+ </ Button >
121+ </ >
122+ ) }
123+
124+ { ! isPendingApproval && (
125+ < Button
126+ variant = { "danger-outline" }
127+ size = { "sm" }
128+ onClick = { openConfirm }
129+ data-cy = { "delete-user" }
130+ disabled = { disabled }
131+ >
132+ < Trash2 size = { 16 } />
133+ Delete
134+ </ Button >
135+ ) }
73136 </ div >
74137 ) ;
75138}
0 commit comments