Skip to content

Commit 708e519

Browse files
authored
suspending/restoring users (#570)
1 parent 9acf524 commit 708e519

File tree

5 files changed

+172
-38
lines changed

5 files changed

+172
-38
lines changed

src/components/ratings/Dropout.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* istanbul ignore file */
22

33
import React from 'react';
4+
import formatDate from '../../utils/formatDate';
45

56
function Dropout({ traineeStatus }: any) {
67
return (
@@ -13,7 +14,7 @@ function Dropout({ traineeStatus }: any) {
1314
Drop Out
1415
</h1>
1516
<div className="pt-6 flex gap-4">
16-
Date :<div>{traineeStatus.date}</div>
17+
Date :<div>{formatDate(traineeStatus?.date)}</div>
1718
</div>
1819
<div className="pt-6 flex gap-4">
1920
Reason:

src/containers/admin-dashBoard/GetRolesQuery.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ const GET_ROLE_QUERY = gql`
1010
id
1111
email
1212
role
13+
status {
14+
status
15+
}
1316
}
1417
}
1518
`;

src/containers/admin-dashBoard/ManagerRoles.tsx

Lines changed: 165 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ import {
2020
import roles from '../../dummyData/roles.json';
2121
import Square from '../../Skeletons/Square';
2222
import { toast } from 'react-toastify';
23-
import { GET_TEAMS } from '../../queries/team.queries';
23+
import { UNDROP_TRAINEE } from '../../Mutations/manageStudentMutations';
2424
import TtlSkeleton from '../../Skeletons/ttl.skeleton';
25+
import GET_TEAMS from '../../queries/team.queries';
2526
const AdminSission = () => {
2627
const { t } = useTranslation();
2728
useDocumentTitle('Roles & Access');
@@ -41,12 +42,17 @@ const AdminSission = () => {
4142
const [users, setUsers] = useState();
4243
const [createUserRole] = useMutation(CREATE_ROLE_MUTATION);
4344
const [updateUserRole] = useMutation(ASSIGN_ROLE_MUTATION);
45+
46+
const [traineeID, setTraineeID] = useState('');
4447
const [findFilter, setFindFilter] = useState('');
4548
const [loggedUser, setLoggedUser] = useState('');
4649
const [allRoles, setallRoles] = useState<any>();
4750
const [selectingTTL, setSelectingTTL] = useState(false);
4851
const [selectedTeamId, setSelectedTeamId] = useState('');
52+
4953
const [deleteConfirmationModel, setDeleteConfirmationModel] = useState(false); // Modal for confirming deletion
54+
const [restoreConfirmationModel, setRestoreConfirmationModel] =
55+
useState(false); // Modal for confirming deletion
5056

5157
const { loading, error, data } = useQuery(GET_TEAMS, {
5258
variables: { orgToken: localStorage.getItem('orgToken') },
@@ -68,10 +74,10 @@ const AdminSission = () => {
6874
const [deleteUser] = useMutation(DELETE_USER_MUTATION, {
6975
onCompleted: (data) => {
7076
if (data.deleteUser.message) {
71-
toast.success('User deleted successfully');
77+
toast.success('User suspended successfully');
7278
setToggle(!toggle); // Refresh or update state
7379
} else {
74-
toast.error('Failed to delete user');
80+
toast.error('Failed to suspended user');
7581
}
7682
},
7783
onError: (error) => {
@@ -180,6 +186,32 @@ const AdminSission = () => {
180186
}, 1000);
181187
},
182188
});
189+
const [unDropTrainee] = useMutation(UNDROP_TRAINEE, {
190+
variables: {
191+
traineeId: traineeID,
192+
},
193+
onCompleted: (data) => {
194+
setTimeout(() => {
195+
// setButtonLoading(false);
196+
if (data.undropTrainee) {
197+
// Check the response structure
198+
// handleAssignRole2();
199+
setToggle(!toggle);
200+
toast.success('User restored successfully');
201+
setRestoreConfirmationModel(false);
202+
} else {
203+
toast.error('Failed to restore trainee');
204+
}
205+
}, 1000);
206+
},
207+
onError: (err) => {
208+
setTimeout(() => {
209+
handleAssignRole2();
210+
console.error('Mutation error:', err); // Log the error
211+
toast.error(err.message);
212+
}, 500);
213+
},
214+
});
183215
/* istanbul ignore next */
184216
const [fetchData2] = useLazyQuery(GET_ROLE_QUERY, {
185217
variables: {
@@ -200,6 +232,7 @@ const AdminSission = () => {
200232
/* istanbul ignore next */
201233
newUsers[index] = {};
202234
newUsers[index].role = user.role;
235+
newUsers[index].status = user?.status?.status;
203236
newUsers[index].email = user.email;
204237
newUsers[index].id = user.id;
205238
if (user.role === 'ttl') {
@@ -248,34 +281,77 @@ const AdminSission = () => {
248281
),
249282
},
250283
{ Header: 'Role', accessor: 'role' },
284+
285+
{
286+
Header: 'Status',
287+
accessor: 'status',
288+
289+
/* istanbul ignore next */
290+
Cell: ({ row }: any) => (
291+
/* istanbul ignore next */
292+
<div className="flex items-left">
293+
<span className="hidden ml-2 md:inline-block h-10 w-10 rounded-full overflow-hidden bg-gray-100 dark:bg-dark-tertiary">
294+
<svg
295+
className="h-full w-full text-gray-300 dark:text-white"
296+
fill="currentColor"
297+
viewBox="0 0 24 24"
298+
>
299+
<path d="M24 20.993V24H0v-2.996A14.977 14.977 0 0112.004 15c4.904 0 9.26 2.354 11.996 5.993zM16.002 8.999a4 4 0 11-8 0 4 4 0 018 0z" />
300+
</svg>
301+
</span>
302+
<div className="flex flex-col leading-4 px-3 py-2">
303+
<p className="text-sm sm:text-xs text-gray-400 dark:text-white">
304+
{row.original.status.status}
305+
</p>
306+
</div>
307+
</div>
308+
),
309+
},
251310
{
252311
Header: 'Action',
253312
accessor: '',
254-
/* istanbul ignore next */
313+
// /* istanbul ignore next */ handleRestoreUser
255314
Cell: ({ row }: any) => (
256315
<div className="flex gap-4">
257-
<p
258-
className="text-red-500 whitespace-no-wrap cursor-pointer"
259-
onClick={
260-
/* istanbul ignore next */ () => {
261-
/* istanbul ignore next */
262-
removeAssignModel(row.original);
263-
}
264-
}
265-
>
266-
{t('Assign')}
267-
</p>
268-
<p
269-
className="text-red-500 whitespace-no-wrap cursor-pointer"
270-
onClick={
271-
/* istanbul ignore next */ () => {
272-
/* istanbul ignore next */
273-
handleDeleteUser(row.original.id);
274-
}
275-
}
276-
>
277-
{t('Delete')}
278-
</p>
316+
{row.original.status.status == 'suspended' ? (
317+
<>
318+
{' '}
319+
<p
320+
className="text-red-500 whitespace-no-wrap cursor-pointer"
321+
onClick={
322+
/* istanbul ignore next */ () => {
323+
handleRestoreUser(row.original.id);
324+
}
325+
}
326+
>
327+
{t('Restore')}
328+
</p>{' '}
329+
</>
330+
) : (
331+
<>
332+
<p
333+
className="text-red-500 whitespace-no-wrap cursor-pointer"
334+
onClick={
335+
/* istanbul ignore next */ () => {
336+
/* istanbul ignore next */
337+
removeAssignModel(row.original);
338+
}
339+
}
340+
>
341+
{t('Assign')}
342+
</p>
343+
<p
344+
className="text-red-500 whitespace-no-wrap cursor-pointer"
345+
onClick={
346+
/* istanbul ignore next */ () => {
347+
handleDeleteUser(row.original.id);
348+
}
349+
}
350+
>
351+
{t('Suspend')}
352+
</p>{' '}
353+
</>
354+
)}
279355
</div>
280356
),
281357
},
@@ -297,7 +373,7 @@ const AdminSission = () => {
297373

298374
const handleDeleteUser = (userId: any) => {
299375
if (loggedUser === userId) {
300-
toast.warn('You can not delete your self!');
376+
toast.warn('You can not suspended your self!');
301377
} else {
302378
setSelectedUser({ id: userId, role: 'user' });
303379
setDeleteConfirmationModel(true);
@@ -313,14 +389,67 @@ const AdminSission = () => {
313389
});
314390
setDeleteConfirmationModel(false);
315391
};
316-
console.log(selectedUser);
317-
392+
const handleRestoreUser = (userId: any) => {
393+
if (!userId) {
394+
toast.warn('No user selected! ');
395+
} else {
396+
setSelectedUser({ id: userId, role: 'user' });
397+
setTraineeID(userId);
398+
setRestoreConfirmationModel(true);
399+
}
400+
};
401+
const confirmRestoreUser = () => {
402+
unDropTrainee({
403+
variables: {
404+
input: { id: selectedUser.id },
405+
context: { userId: selectedUser.id },
406+
},
407+
});
408+
setRestoreConfirmationModel(false);
409+
};
318410
/* istanbul ignore next */
319411
return (
320412
<>
321413
{users && allRoless ? (
322414
<>
323415
{/* ... Existing code ... */}
416+
{/* =========================== Start:: restore Confirmation Modal =============================== */}
417+
<div
418+
className={`w-screen h-screen bg-black bg-opacity-30 backdrop-blur-sm fixed top-0 left-0 z-20 flex items-center justify-center px-4 ${
419+
restoreConfirmationModel === true ? 'block' : 'hidden'
420+
}`}
421+
>
422+
<div className="bg-white dark:bg-dark-bg w-full sm:w-3/4 md:w-1/2 xl:w-4/12 rounded-lg p-4 pb-8">
423+
<div className="card-title w-full flex justify-center items-center flex-col">
424+
<h3 className="font-bold text-sm text-gray-700 dark:text-white text-center w-11/12">
425+
{t('Are you sure you want to restore this user?')}
426+
</h3>
427+
<hr className=" bg-primary border-b my-3 w-full" />
428+
</div>
429+
<div className="card-body">
430+
<div className="w-full flex justify-between">
431+
<Button
432+
variant="info"
433+
size="sm"
434+
style="w-[30%] md:w-1/4 text-sm font-sans"
435+
onClick={() => setRestoreConfirmationModel(false)}
436+
>
437+
{t('Cancel')}
438+
</Button>
439+
<Button
440+
variant="primary"
441+
size="sm"
442+
style="w-[30%] md:w-1/4 text-sm font-sans"
443+
onClick={confirmRestoreUser}
444+
>
445+
{t('Confirm')}
446+
</Button>
447+
</div>
448+
</div>
449+
</div>
450+
</div>
451+
{/* =========================== Start:: restore Session Model =============================== */}
452+
324453
{/* =========================== Start:: Delete Confirmation Modal =============================== */}
325454
<div
326455
className={`w-screen h-screen bg-black bg-opacity-30 backdrop-blur-sm fixed top-0 left-0 z-20 flex items-center justify-center px-4 ${
@@ -330,7 +459,7 @@ const AdminSission = () => {
330459
<div className="bg-white dark:bg-dark-bg w-full sm:w-3/4 md:w-1/2 xl:w-4/12 rounded-lg p-4 pb-8">
331460
<div className="card-title w-full flex justify-center items-center flex-col">
332461
<h3 className="font-bold text-sm text-gray-700 dark:text-white text-center w-11/12">
333-
{t('Are you sure you want to delete this user?')}
462+
{t('Are you sure you want to suspended this user?')}
334463
</h3>
335464
<hr className=" bg-primary border-b my-3 w-full" />
336465
</div>
@@ -421,16 +550,16 @@ const AdminSission = () => {
421550
{/* =========================== End:: delete Session Model =============================== */}
422551
<div className="bg-light-bg dark:bg-dark-frame-bg pb-16 overflow-y-auto overflow-x-hidden">
423552
<div>
424-
<DataTable
425-
data={newUsers.length > 0 ? newUsers : users}
426-
columns={columns}
427-
title="Manageaccess"
428-
/>
553+
<DataTable
554+
data={newUsers.length > 0 ? newUsers : users}
555+
columns={columns}
556+
title="Manageaccess"
557+
/>
429558
</div>
430559
</div>
431560
</>
432561
) : (
433-
<TtlSkeleton/>
562+
<TtlSkeleton />
434563
)}
435564
</>
436565
);

src/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ const specificMessagesToLogout = [
2727
'User not authenticated',
2828
'User account does not exist or has been deleted',
2929
'User with this token no longer exist!!',
30+
'suspend',
31+
'please contact your organization admin for assistance',
3032
];
3133
const errorLink = onError(({ graphQLErrors, networkError }) => {
3234
if (graphQLErrors) {

src/pages/Organization/AdminLogin.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ function AdminLogin() {
4949
// Function to get the redirect_message from the URL and toast it
5050
const showRedirectMessage = () => {
5151
const redirectMessage = searchParams.get('redirect_message');
52-
console.log(redirectMessage);
5352
if (redirectMessage) {
5453
toast.error(redirectMessage);
5554
}

0 commit comments

Comments
 (0)