Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat(drop trainee): Admin/coordinator to drop trainee #281

Merged
merged 2 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,4 @@
"*.{js,ts,tsx}": "eslint --fix",
"*.{js,ts,html,css,md}": "prettier --write \"./**/*.{js,ts,jsx,tsx,json}\""
}
}
}
10 changes: 10 additions & 0 deletions src/Mutations/manageStudentMutations.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// import { gql } from '@apollo/client';
import { gql, ApolloClient, InMemoryCache } from '@apollo/client';

import GET_PROFILE from './User';

export const GET_USERS_QUERY = gql`
query GetUsers($orgToken: String) {
Expand All @@ -11,6 +12,13 @@ export const GET_USERS_QUERY = gql`
}
`;

export const DROP_TRAINEE = gql`
mutation DropTrainee($traineeId: String!, $reason: String!, $date: DateTime!) {
dropTrainee(traineeId: $traineeId, reason: $reason, date: $date)
}
`;


export const GET_TRAINEES_QUERY = gql`
query GetTrainees($orgToken: String) {
getTrainees(orgToken: $orgToken) {
Expand Down Expand Up @@ -62,6 +70,8 @@ export const GET_TRAINEES_QUERY = gql`
}
}
`;


export const GET_COHORT_TRAINEES_QUERY = gql`
query GetCohortTrainees($cohort: String, $orgToken: String) {
getCohortTrainees(cohort: $cohort, orgToken: $orgToken) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/ratings/AddNewRatings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -207,4 +207,4 @@ function AddNewRatings({
);
}

export default AddNewRatings;
export default AddNewRatings;
2 changes: 1 addition & 1 deletion src/components/ratings/ViewWeeklyRatings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -251,4 +251,4 @@ function ViewSprintRatings({
);
}

export default ViewSprintRatings;
export default ViewSprintRatings;
2 changes: 1 addition & 1 deletion src/components/ratings/hooks/useAddNewRating.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,4 @@ const useAddRating = ({
};
};

export default useAddRating;
export default useAddRating;
7 changes: 4 additions & 3 deletions src/containers/DashRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@ const AdminManageRoles = React.lazy(
const AdminTraineeDashboard = React.lazy(
() => import('../pages/AdminTraineeDashboard'),
);
const TtlTraineeDashboard = React.lazy(
() => import('../pages/ttlTraineeDashboard'),
);
const ViewTraineeRatings = React.lazy(
() => import('../pages/ratings/ViewTraineeRatings'),
);
const TtlTraineeDashboard = React.lazy(
() => import('../pages/ttlTraineeDashboard'),
);

const TraineeRatingDashboard = React.lazy(
() => import('../pages/TraineeRatingDashboard'),
);
Expand Down
2 changes: 1 addition & 1 deletion src/containers/admin-dashBoard/TtlsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ export default function TtlsPage() {
accessor: 'team.name',
Cell: ({ value }: { value: string }) => value || t('Not assigned'),
},

{
Header: t('action'),
accessor: '',
Expand Down
223 changes: 203 additions & 20 deletions src/pages/AdminTraineeDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
GET_TRAINEES_QUERY,
GET_COHORTS_QUERY,
REMOVE_MEMBER_FROM_COHORT_MUTATION,
DROP_TRAINEE,
EDIT_MEMBER_MUTATION,
INVITE_USER_MUTATION,
GET_TEAM_QUERY,
Expand Down Expand Up @@ -56,12 +57,13 @@ function AdminTraineeDashboard() {
const [traineeDetails, setTraineeDetails] = useState<any>({});
const [selectedOption, setSelectedOption] = useState<any[]>([]);
const [selectedOptionUpdate, setSelectedOptionUpdate] = useState<any>({});
const [dropTraineeModel, setDropTraineeModel] = useState(false);
const [dropTraineeID, setdropTraineeID] = useState('');
const [selectedTeamOptionUpdate, setSelectedTeamOptionUpdate] = useState<any>(
{},
);
const [selectedTeamOption, setSelectedTeamOption] = useState<any[]>([]);
const [deleteEmail, setDeleteEmail] = useState('');
const [deleteFromCohort, setDeleteFromCohort] = useState('');
const [editEmail, setEditEmail] = useState('');
const [editCohort, setEditCohort] = useState('');
const [editTeam, setEditTeam] = useState('');
Expand All @@ -87,9 +89,23 @@ function AdminTraineeDashboard() {
);
}

const [deleteFromCohort, setDeleteFromCohort] = useState('');
//const [status, setStatus] = useState(row.original?.Status?.status);
// Define state variables to store reason and date
const [reason, setReason] = useState('');
// const [date, setDate] = useState('');
const currentDate = new Date().toISOString().split('T')[0]; // Get the current date

// Function to handle the reason input change
const handleReasonChange = (event: {
target: { value: React.SetStateAction<string> };
}) => {
const newReason = event.target.value;
setReason(newReason);
};

const [getGitHubStatistics] = useLazyQuery(GET_GITHUB_STATISTICS, {
onCompleted: (data) => {
console.log(data);
setGitHubStatistics(data.gitHubActivity);
setIsLoaded(false);
},
Expand Down Expand Up @@ -130,6 +146,28 @@ function AdminTraineeDashboard() {
setRegisterTraineeModel(newState);
};

const dropModel = async (rowData: any) => {
const filteredUser = traineeData.filter(
(item: any) => item.email == rowData,
);
if (filteredUser.length > 0) {
const user = filteredUser[0];
if (
user.profile &&
user.profile.user &&
user.profile.user.status &&
user.profile.user.status.status
) {
if (user.profile.user.status.status !== 'drop') {
let newState = !dropTraineeModel;
setDropTraineeModel(newState);
} else {
toast.success('Trainee is already dropped');
}
}
}
};

/* istanbul ignore next */
const removeEditModel = () => {
const newState = !editTraineeModel;
Expand Down Expand Up @@ -179,24 +217,32 @@ function AdminTraineeDashboard() {
{ Header: t('cohort'), accessor: 'cohort' },
{ Header: t('program'), accessor: 'program' },
{
Header: t('View'),
accessor: '',
Cell: ({ row }: any) => (
<div
className={
' items-center' + (traineeData?.length > 0 ? ' flex' : ' hidden')
}
>
<button
className="bg-black text-white rounded-xl px-3"
onClick={() => {
navigate(`/trainees/${row.original.userId}`);
}}
Header: t('Status'),
accessor: 'status',

Cell: ({ row }: any) => {
return (
<div
className={
' items-center' + (traineeData?.length > 0 ? ' flex' : ' hidden')
}
>
{t('View')}
</button>
</div>
),
<button
// className="bg-black text-white rounded-xl px-3 "
className={`${
row.original?.Status?.status === 'drop'
? ' bg-gray-500'
: 'bg-black'
} text-white rounded-xl px-3`}
onClick={() => {
navigate(`/trainees/${row.original.userId}`);
}}
>
{row.original?.Status?.status === 'drop' ? 'Dropped' : 'view'}
</button>
</div>
);
},
},

{
Expand Down Expand Up @@ -245,6 +291,20 @@ function AdminTraineeDashboard() {
}}
/>

<Icon
icon="mdi:close-circle"
width="30"
height="30"
cursor="pointer"
color="#9e85f5"
/* istanbul ignore next */
onClick={() => {
dropModel(row.original.email);
setdropTraineeID(row.original.userId);
setReason(row.original.reason);
}}
/>

<Icon
icon="flat-color-icons:view-details"
width="30"
Expand Down Expand Up @@ -304,18 +364,20 @@ function AdminTraineeDashboard() {
},
});
}

/* istanbul ignore if */

if (traineeData && traineeData.length > 0) {
traineeData?.map((data: any, index: number) => {
datum[index] = {};
datum[index].name = data.profile ? data.profile.name : 'undefined';
datum[index].email = data.email;
datum[index].rating = data?.ratings?.at(-1)?.average || 0;
datum[index].rating = '2';
datum[index].team = data.team?.name;
datum[index].cohort = data.team?.cohort?.name;
datum[index].program = data.team?.cohort?.program?.name;
datum[index].userId = data.profile?.user?.id;
datum[index].Status = data.profile?.user?.status;
});
}

Expand Down Expand Up @@ -366,6 +428,34 @@ function AdminTraineeDashboard() {
},
});

const [dropMemberFromCohort] = useMutation(DROP_TRAINEE, {
variables: {
traineeId: dropTraineeID,
reason: reason,
date: currentDate,
},
onCompleted: (data) => {
setTimeout(() => {
setButtonLoading(false);
if (data.dropTrainee) {
// Check the response structure
refetch();
toast.success('Trainee dropped successfully');
setDropTraineeModel(false);
} else {
toast.error('Failed to drop trainee');
}
}, 1000);
},
onError: (err) => {
setTimeout(() => {
setButtonLoading(false);
console.error('Mutation error:', err); // Log the error
toast.error(err.message);
}, 500);
},
});

const [removeMemberFromCohort] = useMutation(
REMOVE_MEMBER_FROM_COHORT_MUTATION,
{
Expand Down Expand Up @@ -962,6 +1052,99 @@ function AdminTraineeDashboard() {
</div>
{/* =========================== End:: RemoveTraineeModel =============================== */}

{/* =========================== start:: deleteTraineeModel =============================== */}
<div
className={`h-screen w-screen z-20 bg-black bg-opacity-30 backdrop-blur-sm fixed flex items-center justify-center px-4 top-0 left-0 ${
dropTraineeModel === true ? 'block' : 'hidden'
}`}
>
<div className="w-full p-4 pb-8 bg-white rounded-lg dark:bg-dark-bg sm:w-3/4 xl:w-4/12">
<div className="flex flex-wrap items-center justify-center w-full card-title">
<h3 className="w-11/12 text-sm font-bold text-center dark:text-white">
{t('Drop Trainee')}
</h3>
<hr className="w-full my-3 border-b bg-primary" />
</div>
<div className="card-body">
<form className="px-8 py-3">
{/* ... (rest of your form) */}

{/* Reason Field */}
<div className="mb-4">
<label
className="block text-sm font-bold text-gray-700 dark:text-white"
htmlFor="reason"
>
{t('Reason')}
</label>
<input
type="text"
id="reason"
name="reason"
value={reason}
onChange={handleReasonChange} // Capture reason input value
className="mt-1 px-3 py-2 w-full border border-gray-300 rounded-md focus:outline-none focus:ring focus:ring-primary dark:bg-dark-bg dark:text-white"
/>
</div>

{/* Date Field */}
<div className="mb-4">
<label
className="block text-sm font-bold text-gray-700 dark:text-white"
htmlFor="date"
>
{t('Date')}
</label>
<input
type="text" // Change the input type to text
id="date"
name="date"
value={currentDate} // Set the value to the current date
readOnly // Make the input read-only
className="mt-1 px-3 py-2 w-full border border-gray-300 rounded-md focus:outline-none focus:ring focus:ring-primary dark:bg-dark-bg dark:text-white"
/>
</div>

<div className="flex justify-between w-full">
<Button
data-testid="dropModel"
variant="info"
size="sm"
style="w-[30%] md:w-1/4 text-sm font-sans"
onClick={() => setDropTraineeModel(false)}
>
{t('Cancel')}
</Button>

<Button
variant="primary"
size="sm"
data-testid="dropMemberFromCohort"
style="w-[30%] md:w-1/4 text-sm font-sans"
onClick={() => {
setButtonLoading(true);

if (dropTraineeID && reason) {
// also pass the reason value to the dropMemberFromCohort function
dropMemberFromCohort();
} else {
toast.error(
'Please enter a reason for dropping the trainee',
);
}
}}
loading={buttonLoading}
>
{t('Drop Trainee')}
</Button>
</div>
</form>
</div>
</div>
</div>

{/* =========================== End:: deleteTraineeModel =============================== */}

{/* =========================== Start:: AddTraineeModel =============================== */}

<div
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@
"src/tests/about.test.tsx"
, "src/components/TraineeDashboardChart.tsx", "src/pages/TraineeRatingDashboard.tsx" ],
"exclude": ["node_modules"]
}
}
Loading
Loading