Skip to content

Commit b37dc08

Browse files
committed
fix-coordinators-table
1 parent 31852e3 commit b37dc08

File tree

7 files changed

+900
-266
lines changed

7 files changed

+900
-266
lines changed

src/Mutations/User.tsx

+11
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ export const DROP_TTL_USER = gql`
66
}
77
`;
88

9+
export const DROP_COORDINATOR = gql`
10+
mutation DropCordinator($id: String!, $reason: String!) {
11+
dropCordinator(id: $id, reason: $reason)
12+
}
13+
`;
14+
export const UNDROP_COORDINATOR = gql`
15+
mutation UndropCordinator($id: String!) {
16+
undropCordinator(id: $id)
17+
}
18+
`;
19+
920
export const UNDROP_TTL_USER = gql`
1021
mutation UnDropTTLUser($email: String!) {
1122
undropTTLUser(email: $email)

src/components/DataTable.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ function DataTable({ data, columns, title, loading, className }: TableData) {
9191
>
9292
<thead>
9393
{headerGroups.map((headerGroup) => (
94-
<tr {...headerGroup.getHeaderGroupProps()} key={headerGroup.id}>
94+
<tr {...headerGroup.getHeaderGroupProps()}>
9595
{headerGroup.headers.map((column) => (
9696
<th
9797
className={`thead ${column.isSorted ? 'sort-asc' : ''}`}

src/components/DropOrUndropUser.tsx

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import React, { useState } from 'react';
2+
import { useTranslation } from 'react-i18next';
3+
import Button from './Buttons';
4+
5+
interface DropOrUndropUserProps {
6+
subject: string;
7+
title: string;
8+
drop?: boolean;
9+
loading: boolean;
10+
setRemovalReason?: React.Dispatch<React.SetStateAction<string>>;
11+
onSubmit: (data: React.MouseEvent<HTMLButtonElement>) => void;
12+
onClose: () => void;
13+
}
14+
15+
function DropOrUndropUser({
16+
subject,
17+
title,
18+
drop,
19+
loading,
20+
setRemovalReason,
21+
onSubmit,
22+
onClose,
23+
}: DropOrUndropUserProps) {
24+
const { t } = useTranslation();
25+
const [reason, setReason] = useState('');
26+
27+
const handleConfirm = (e: React.MouseEvent<HTMLButtonElement>) => {
28+
e.stopPropagation();
29+
if (onSubmit) onSubmit(e);
30+
};
31+
32+
return (
33+
<div 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">
34+
<div className="w-full p-4 pb-8 bg-white rounded-lg dark:bg-dark-bg sm:w-3/4 xl:w-4/12">
35+
<div className="flex flex-wrap items-center justify-center w-full card-title ">
36+
<h3 className="w-11/12 text-sm font-bold text-center dark:text-white ">
37+
{t(subject)}
38+
</h3>
39+
<hr className="w-full my-3 border-b bg-primary" />
40+
</div>
41+
<div className="card-body w-full">
42+
<form className="px-8 py-3 w-full">
43+
<div className="flex flex-wrap items-center justify-center w-full card-title ">
44+
<h3 className="w-11/12 text-sm font-bold text-center dark:text-white ">
45+
{t(title)}
46+
</h3>
47+
</div>
48+
{/* Reason input field */}
49+
{drop && (
50+
<div className="mt-4">
51+
<input
52+
type="text"
53+
className="mt-1 p-2 block w-full border rounded-md shadow-sm focus:ring focus:ring-opacity-50 focus:ring-primary dark:bg-dark-bg dark:border-gray-600 dark:text-white"
54+
placeholder={t('Enter reason')}
55+
value={reason}
56+
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
57+
setReason(e.target.value)
58+
}
59+
id="removalReason"
60+
/>
61+
<p
62+
id="errorMessage"
63+
className="text-red-500 text-xs mt-1 hidden"
64+
>
65+
Reason is required!
66+
</p>
67+
</div>
68+
)}
69+
70+
<div className="flex justify-between w-full pt-3">
71+
<Button
72+
data-testid="removeModel2"
73+
variant="info"
74+
size="sm"
75+
style="w-[8rem] h-[2.3rem] text-sm p-0 mx-0 flex justify-center items-center"
76+
onClick={() => {
77+
if (drop) {
78+
setReason('');
79+
document
80+
.getElementById('errorMessage')!
81+
.classList.add('hidden');
82+
}
83+
onClose();
84+
}}
85+
>
86+
{t('Cancel')}
87+
</Button>
88+
<Button
89+
variant="primary"
90+
size="sm"
91+
style="w-[8rem] h-[2.3rem] text-sm p-0 mx-0 flex justify-center items-center"
92+
onClick={() => {
93+
if (!reason.trim() && drop) {
94+
document
95+
.getElementById('errorMessage')!
96+
.classList.remove('hidden');
97+
} else {
98+
if (drop && setRemovalReason) {
99+
setRemovalReason(reason);
100+
}
101+
handleConfirm(
102+
new MouseEvent(
103+
'click',
104+
) as unknown as React.MouseEvent<HTMLButtonElement>,
105+
);
106+
}
107+
}}
108+
loading={loading}
109+
>
110+
{loading ? t('Loading') : t('Proceed')}
111+
</Button>
112+
</div>
113+
</form>
114+
</div>
115+
</div>
116+
</div>
117+
);
118+
}
119+
120+
export default DropOrUndropUser;

src/components/ProgramUsersModal.tsx

+14-14
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import React from 'react';
22
import { gql, useQuery } from '@apollo/client';
3-
import DataTable from './DataTable';
43
import Dialog from '@mui/material/Dialog';
54
import DialogContent from '@mui/material/DialogContent';
65
import DialogTitle from '@mui/material/DialogTitle';
76
import { styled } from '@mui/material/styles';
7+
import DataTable from './DataTable';
88

99
interface User {
1010
email: string;
@@ -70,7 +70,7 @@ export function ProgramUsersModal({
7070
isOpen,
7171
onClose,
7272
// defaultProgram = 'default',
73-
programName
73+
programName,
7474
}: ProgramUsersModalProps) {
7575
const { data, loading, error } = useQuery(GET_ALL_USERS, {
7676
variables: {
@@ -79,10 +79,11 @@ export function ProgramUsersModal({
7979
skip: !isOpen,
8080
});
8181

82-
const programUsers = data?.getAllUsers.filter(
83-
(user: User) => user.team?.cohort?.program?.name === programName
82+
const programUsers =
83+
data?.getAllUsers.filter(
84+
(user: User) => user.team?.cohort?.program?.name === programName,
8485
// || (user.team === null && programName === defaultProgram)
85-
) || [];
86+
) || [];
8687

8788
const columns = [
8889
{
@@ -91,7 +92,11 @@ export function ProgramUsersModal({
9192
Cell: ({ value }: CellProps) => (
9293
<div className="flex items-center">
9394
<span className="hidden ml-2 md:inline-block h-8 w-8 rounded-full overflow-hidden bg-gray-100 dark:bg-gray-700">
94-
<svg className="h-full w-full text-gray-300 dark:text-gray-500" fill="currentColor" viewBox="0 0 24 24">
95+
<svg
96+
className="h-full w-full text-gray-300 dark:text-gray-500"
97+
fill="currentColor"
98+
viewBox="0 0 24 24"
99+
>
95100
<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" />
96101
</svg>
97102
</span>
@@ -119,7 +124,7 @@ export function ProgramUsersModal({
119124
if (loading) {
120125
return (
121126
<div className="flex justify-center items-center h-48">
122-
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
127+
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary" />
123128
</div>
124129
);
125130
}
@@ -152,12 +157,7 @@ export function ProgramUsersModal({
152157
};
153158

154159
return (
155-
<StyledDialog
156-
open={isOpen}
157-
onClose={onClose}
158-
maxWidth="md"
159-
fullWidth
160-
>
160+
<StyledDialog open={isOpen} onClose={onClose} maxWidth="md" fullWidth>
161161
<div className="bg-white dark:bg-gray-800 rounded-t-lg">
162162
<StyledDialogTitle className="text-gray-900 dark:text-white border-b dark:border-gray-700">
163163
{programName} - Users
@@ -168,4 +168,4 @@ export function ProgramUsersModal({
168168
</div>
169169
</StyledDialog>
170170
);
171-
}
171+
}

0 commit comments

Comments
 (0)