Skip to content

Commit

Permalink
Feat(drop trainee): Admin/coordinator to drop trainee (#281)
Browse files Browse the repository at this point in the history
* Rating Feature Implementation

* feat: drop trainee

---------

Co-authored-by: Aline096 <[email protected]>
  • Loading branch information
Martha-Iradukunda and Aline-Uwera authored Oct 12, 2023
1 parent b8597c2 commit ec4eacd
Show file tree
Hide file tree
Showing 11 changed files with 225 additions and 31 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,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 @@ -961,6 +1051,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

1 comment on commit ec4eacd

@vercel
Copy link

@vercel vercel bot commented on ec4eacd Oct 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

metron-devpulse – ./

metron-devpulse.vercel.app
metron-devpulse-git-develop-metron.vercel.app
metron-devpulse-metron.vercel.app

Please sign in to comment.