Skip to content

Commit 39de1df

Browse files
committed
adding undrop trainee feature
1 parent 266d7ed commit 39de1df

File tree

4 files changed

+195
-73
lines changed

4 files changed

+195
-73
lines changed

src/Mutations/manageStudentMutations.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@ export const DROP_TRAINEE = gql`
2121
dropTrainee(traineeId: $traineeId, reason: $reason, date: $date)
2222
}
2323
`;
24-
24+
// Define the mutation
25+
export const UNDROP_TRAINEE = gql`
26+
mutation UndropTrainee($traineeId: String!) {
27+
undropTrainee(traineeId: $traineeId)
28+
}
29+
`;
2530
export const GET_TRAINEES_QUERY = gql`
2631
query GetTrainees($orgToken: String) {
2732
getTrainees(orgToken: $orgToken) {

src/pages/AdminTraineeDashboard.tsx

Lines changed: 179 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
GET_TEAM_QUERY,
2828
ADD_MEMBER_TO_TEAM,
2929
GET_GITHUB_STATISTICS,
30+
UNDROP_TRAINEE,
3031
} from '../Mutations/manageStudentMutations';
3132
import { useNavigate } from 'react-router-dom';
3233

@@ -70,6 +71,8 @@ function AdminTraineeDashboard() {
7071
const [editTeam, setEditTeam] = useState('');
7172
const [inviteEmail, setInviteEmail] = useState('');
7273
const [buttonLoading, setButtonLoading] = useState(false);
74+
const [restoreTraineeModel, setRestoreTraineeModel] = useState(false);
75+
7376
const [toggle, setToggle] = useState(false);
7477
const [showOptions, setShowOptions] = useState(false);
7578
const options: any = [];
@@ -81,9 +84,11 @@ function AdminTraineeDashboard() {
8184
const { traineeData, setAllTrainees } = useTraineesContext() || [];
8285
const [actionTraineeOptions, setActionTraineeOptions] = useState<any>(null);
8386
const modalRef = useRef<any>(null);
84-
85-
const [selectedTraineeId, setSelectedTraineeId]= useState<string[]>()
86-
87+
// restoreTraineeModel
88+
// restoreTraineeMod
89+
// unDropTrainee
90+
// restoreMemberFromCohort
91+
const [selectedTraineeId, setSelectedTraineeId] = useState<string[]>();
8792

8893
useEffect(() => {
8994
const handleClickOutside = (event: any) => {
@@ -168,7 +173,10 @@ function AdminTraineeDashboard() {
168173
const newState = !removeTraineeModel;
169174
setRemoveTraineeModel(newState);
170175
};
171-
176+
const restoreTraineeMod = () => {
177+
const newState = !restoreTraineeModel;
178+
setRestoreTraineeModel(newState);
179+
};
172180
const removeModel = () => {
173181
const newState = !registerTraineeModel;
174182
setRegisterTraineeModel(newState);
@@ -264,18 +272,18 @@ function AdminTraineeDashboard() {
264272
}
265273
>
266274
<button
267-
className={`${row.original?.Status?.status === 'drop'
268-
? 'bg-gray-500'
269-
: 'bg-black'
270-
} text-white rounded-xl px-3`}
271-
onClick={() => {
272-
setSelectedTraineeId(row.original?.email);
273-
handleClickOpen2();
274-
}}
275-
>
276-
{row.original?.Status?.status === 'drop' ? 'Dropped' : 'View'}
277-
</button>
278-
275+
className={`${
276+
row.original?.Status?.status === 'drop'
277+
? 'bg-gray-500'
278+
: 'bg-black'
279+
} text-white rounded-xl px-3`}
280+
onClick={() => {
281+
setSelectedTraineeId(row.original?.email);
282+
handleClickOpen2();
283+
}}
284+
>
285+
{row.original?.Status?.status === 'drop' ? 'Dropped' : 'View'}
286+
</button>
279287
</div>
280288
);
281289
},
@@ -296,8 +304,9 @@ function AdminTraineeDashboard() {
296304
/>
297305
{selectedRow === row.original.email && (
298306
<div
299-
ref={modalRef}
300-
className="absolute z-50 w-64 p-4 mt-2 overflow-hidden border border-gray-300 rounded-lg shadow-md dropdown right-4 bg-light-bg max-h-30 dark:bg-dark-bg">
307+
ref={modalRef}
308+
className="absolute z-50 w-64 p-4 mt-2 overflow-hidden border border-gray-300 rounded-lg shadow-md dropdown right-4 bg-light-bg max-h-30 dark:bg-dark-bg"
309+
>
301310
<>
302311
<div className="mb-4"></div>
303312
<div className="mb-4">
@@ -363,30 +372,58 @@ function AdminTraineeDashboard() {
363372
</div>
364373
</div>
365374
<div className="mb-4">
366-
<div
367-
className="flex items-center p-2 rounded-md cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800"
368-
onClick={() => {
369-
dropModel(row.original.email);
370-
setdropTraineeID(row.original.userId);
371-
setReason(row.original.reason);
372-
toggleOptions(row.original.email);
373-
}}
374-
>
375-
<Icon
376-
icon="mdi:close-circle"
377-
width="40"
378-
height="40"
379-
cursor="pointer"
380-
color="#9e85f5"
381-
/>
382-
<div>
383-
<span className="font-bold">Drop</span>{' '}
384-
<>
385-
<br />
386-
Drop trainee
387-
</>
375+
{row.original?.Status?.status !== 'drop' ? (
376+
<div
377+
className="flex items-center p-2 rounded-md cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800"
378+
onClick={() => {
379+
dropModel(row.original.email);
380+
setdropTraineeID(row.original.userId);
381+
setReason(row.original.reason);
382+
toggleOptions(row.original.email);
383+
}}
384+
>
385+
<Icon
386+
icon="mdi:close-circle"
387+
width="40"
388+
height="40"
389+
cursor="pointer"
390+
color="#9e85f5"
391+
/>
392+
<div>
393+
<span className="font-bold">Drop</span>
394+
{row.original.status}
395+
<>
396+
<br />
397+
Drop trainee
398+
</>
399+
</div>
388400
</div>
389-
</div>
401+
) : (
402+
<div
403+
className="flex items-center p-2 rounded-md cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800"
404+
onClick={() => {
405+
restoreTraineeMod();
406+
setdropTraineeID(row.original.userId);
407+
setReason(row.original.reason);
408+
toggleOptions(row.original.email);
409+
}}
410+
>
411+
<Icon
412+
icon="mdi:close-circle"
413+
width="40"
414+
height="40"
415+
cursor="pointer"
416+
color="#9e85f5"
417+
/>
418+
<div>
419+
<span className="font-bold">Restore</span>{' '}
420+
<>
421+
<br />
422+
Restore Dropped Trainee
423+
</>
424+
</div>
425+
</div>
426+
)}
390427
</div>
391428
<div>
392429
<div
@@ -559,6 +596,32 @@ function AdminTraineeDashboard() {
559596
},
560597
});
561598

599+
const [unDropTrainee] = useMutation(UNDROP_TRAINEE, {
600+
variables: {
601+
traineeId: dropTraineeID,
602+
},
603+
onCompleted: (data) => {
604+
setTimeout(() => {
605+
setButtonLoading(false);
606+
if (data.undropTrainee) {
607+
// Check the response structure
608+
refetch();
609+
toast.success('Trainee Undropped successfully');
610+
setDropTraineeModel(false);
611+
restoreTraineeMod();
612+
} else {
613+
toast.error('Failed to undrop trainee');
614+
}
615+
}, 1000);
616+
},
617+
onError: (err) => {
618+
setTimeout(() => {
619+
setButtonLoading(false);
620+
console.error('Mutation error:', err); // Log the error
621+
toast.error(err.message);
622+
}, 500);
623+
},
624+
});
562625
const [removeMemberFromCohort] = useMutation(
563626
REMOVE_MEMBER_FROM_COHORT_MUTATION,
564627
{
@@ -658,7 +721,6 @@ function AdminTraineeDashboard() {
658721
teamOptions[index].label = team?.name;
659722
});
660723
}
661-
662724

663725
return (
664726
<>
@@ -672,20 +734,21 @@ function AdminTraineeDashboard() {
672734
className="rounded-lg"
673735
fullWidth
674736
>
675-
{traineeData?.map((data:any) => {
676-
if (data.email === selectedTraineeId) {
677-
return <ViewWeeklyRatings
678-
traineeName={data?.profile?.name || 'Unknown Name'}
679-
traineeEmail={data?.email || 'Unknown Email'}
680-
traineeId={data?.profile?.user?.id || 'Unknown ID'}
681-
traineeCohort={data?.team?.cohort?.id || 'Unknown Cohort'}
682-
traineeStatus={
683-
data?.profile?.user?.status || 'Status Unavailable'
684-
}
685-
/>
737+
{traineeData?.map((data: any) => {
738+
if (data.email === selectedTraineeId) {
739+
return (
740+
<ViewWeeklyRatings
741+
traineeName={data?.profile?.name || 'Unknown Name'}
742+
traineeEmail={data?.email || 'Unknown Email'}
743+
traineeId={data?.profile?.user?.id || 'Unknown ID'}
744+
traineeCohort={data?.team?.cohort?.id || 'Unknown Cohort'}
745+
traineeStatus={
746+
data?.profile?.user?.status || 'Status Unavailable'
747+
}
748+
/>
749+
);
686750
}
687-
}
688-
)}
751+
})}
689752
<FaTimes
690753
size={24}
691754
color="red"
@@ -1473,6 +1536,57 @@ function AdminTraineeDashboard() {
14731536
</div>
14741537
</div>
14751538
{/* =========================== End:: AddTraineeModel =============================== */}
1539+
{/* =========================== Start:: RestoreTraineeModel =============================== */}
1540+
1541+
<div
1542+
className={`h-screen w-screen bg-black bg-opacity-30 backdrop-blur-sm fixed top-0 left-0 z-20 flex items-center justify-center px-4 ${
1543+
restoreTraineeModel === true ? 'block' : 'hidden'
1544+
}`}
1545+
>
1546+
<div className="w-full p-4 pb-8 bg-white rounded-lg dark:bg-dark-bg sm:w-3/4 xl:w-4/12">
1547+
<div className="flex flex-wrap items-center justify-center w-full card-title ">
1548+
<h3 className="w-11/12 text-sm font-bold text-center dark:text-white ">
1549+
{t('Restore Trainee')}
1550+
</h3>
1551+
<hr className="w-full my-3 border-b bg-primary" />
1552+
</div>
1553+
<div className="card-body">
1554+
<form className="px-8 py-3 ">
1555+
<div className="flex flex-wrap items-center justify-center w-full card-title ">
1556+
<h3 className="w-11/12 text-sm font-bold text-center dark:text-white ">
1557+
{t('Are you sure you want to undrop this trainee?')}
1558+
</h3>
1559+
</div>
1560+
1561+
<div className="flex justify-between w-full">
1562+
<Button
1563+
data-testid="restoreModel2"
1564+
variant="info"
1565+
size="sm"
1566+
style="w-[40%] md:w-1/4 text-sm font-sans"
1567+
onClick={() => restoreTraineeMod()}
1568+
>
1569+
{t('Cancel')}
1570+
</Button>
1571+
<Button
1572+
variant="primary"
1573+
size="sm"
1574+
data-testid="restoreMemberFromCohort"
1575+
style="w-[40%] md:w-1/4 text-sm font-sans"
1576+
onClick={() => {
1577+
setButtonLoading(true);
1578+
unDropTrainee();
1579+
}}
1580+
loading={buttonLoading}
1581+
>
1582+
{t('Proceed')}
1583+
</Button>
1584+
</div>
1585+
</form>
1586+
</div>
1587+
</div>
1588+
</div>
1589+
{/* =========================== End:: RemoveTraineeModel =============================== */}
14761590

14771591
<div className="flex flex-col">
14781592
<div className="flex flex-row">
@@ -1507,15 +1621,15 @@ function AdminTraineeDashboard() {
15071621
</div>
15081622
</div>
15091623
<div className="">
1510-
{loading? (
1511-
<TtlSkeleton/>
1512-
):(
1513-
<DataTable
1514-
data={traineeData?.length > 0 ? datum : []}
1515-
columns={columns}
1516-
loading={loading}
1517-
title={t('Trainee list')}
1518-
/>
1624+
{loading ? (
1625+
<TtlSkeleton />
1626+
) : (
1627+
<DataTable
1628+
data={traineeData?.length > 0 ? datum : []}
1629+
columns={columns}
1630+
loading={loading}
1631+
title={t('Trainee list')}
1632+
/>
15191633
)}
15201634
</div>
15211635
</div>
@@ -1527,4 +1641,4 @@ function AdminTraineeDashboard() {
15271641
);
15281642
}
15291643

1530-
export default AdminTraineeDashboard;
1644+
export default AdminTraineeDashboard;

src/pages/GradingSystem.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import GRADING_SYSTEM_QUERY from './GradingSystemQuery';
1313
import MAKE_DEFAULT_GRADING_SYSTEM from '../Mutations/MakeDefault';
1414
import GRADING_SYSTEM_MUTATION from './GradingSystemMutation';
1515
import AddGradingSystem from './gradeSystem/addNew';
16-
import GradingSkeleton from '../Skeletons/gradingSkeleton'
16+
import GradingSkeleton from '../Skeletons/gradingSkeleton';
17+
1718
type grade = {
1819
grade?: string;
1920
range?: string;
@@ -278,12 +279,12 @@ function GradingSystem() {
278279
{value === '' && (
279280
<div className="">
280281
<div className="max-w-full">
281-
<DataTable
282-
columns={GradingsColumn}
283-
loading={gradeLoading}
284-
data={gradingData}
285-
title={t('Gradings List')}
286-
/>
282+
<DataTable
283+
columns={GradingsColumn}
284+
loading={gradeLoading}
285+
data={gradingData}
286+
title={t('Gradings List')}
287+
/>
287288
</div>
288289
</div>
289290
)}

src/pages/Organization/AdminLogin.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ function AdminLogin() {
106106
},
107107
onError: (err) => {
108108
/* istanbul ignore next */
109+
console.log(err.message);
110+
109111
if (err.networkError)
110112
toast.error('There was a problem contacting the server');
111113
else if (err.message.toLowerCase() !== 'invalid credential') {

0 commit comments

Comments
 (0)