Skip to content

Commit f0d1c91

Browse files
Ndevu12Calebgisa72
andauthored
fix-trainee-profile-page (#489) (#493)
Co-authored-by: Gisa Mugisha Caleb Pacifique <[email protected]>
1 parent 02d9bb0 commit f0d1c91

File tree

4 files changed

+152
-42
lines changed

4 files changed

+152
-42
lines changed

src/components/InvitationTable.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,4 +179,4 @@ function DataTableStats({ data, columns, error, loading }: TableData) {
179179
}
180180

181181

182-
export default DataTableStats;
182+
export default DataTableStats;

src/containers/DashRoutes.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ function DashRoutes() {
9393
<DashHeader />
9494
<Sidebar toggle={toggleNav} style="" />
9595
</MenuProvider>
96-
<main className=" px-4 md:px-8 py-4 md:py-8 w-[100%] bg-light-bg dark:bg-dark-frame-bg">
96+
<main className=" px-4 md:px-8 py-4 md:py-8 w-[100%] bg-light-bg dark:bg-dark-frame-bg">
9797
<Suspense fallback={<Square />}>
9898
<Routes>
9999
<Route path="/dashboard" element={<Dashboard />} />

src/pages/invitation.tsx

Lines changed: 102 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -17,37 +17,7 @@ import { useTranslation } from 'react-i18next';
1717
import { Icon } from '@iconify/react';
1818
import { DELETE_INVITATION } from '../Mutations/invitationMutation';
1919
import Button from '../components/Buttons';
20-
21-
const GET_ALL_INVITATIONS = gql`
22-
query AllInvitations{
23-
getAllInvitations{
24-
invitations {
25-
invitees {
26-
email
27-
role
28-
}
29-
id
30-
status
31-
}
32-
totalInvitations
33-
}
34-
}
35-
`;
36-
37-
const GET_INVITATIONS = gql`
38-
query GetInvitations($query: String!) {
39-
getInvitations(query: $query) {
40-
invitations {
41-
invitees {
42-
email
43-
role
44-
}
45-
id
46-
status
47-
}
48-
}
49-
}
50-
`;
20+
import { GET_ALL_INVITATIONS, GET_INVITATIONS, GET_ROLES_AND_STATUSES } from '../queries/invitation.queries';
5121

5222
interface Invitee {
5323
email: string;
@@ -79,7 +49,11 @@ function Invitation() {
7949
const [removeInviteeModel, setRemoveInviteeModel] = useState(false);
8050
const [deleteInvitation, setDeleteInvitation] = useState('');
8151
const [buttonLoading, setButtonLoading] = useState(false);
82-
52+
const [selectedRole, setSelectedRole] = useState('');
53+
const [selectedStatus, setSelectedStatus] = useState('');
54+
const [filterVariables, setFilterVariables] = useState({ role: '', status: '' });
55+
56+
8357
const organizationToken = localStorage.getItem('orgToken');
8458

8559
const parseRange = (range: string) => {
@@ -113,6 +87,7 @@ function Invitation() {
11387
toast.error('testtes111');
11488
},
11589
});
90+
11691
useEffect(() => {
11792
if (isLoading) {
11893
setFilterLoading(true);
@@ -133,6 +108,7 @@ function Invitation() {
133108
const { name, value } = e.target;
134109
setCustomRange((prev) => ({ ...prev, [name]: value }));
135110
};
111+
136112
if (!organizationToken) {
137113
return <p>Organization token not found. Please log in.</p>;
138114
}
@@ -143,21 +119,40 @@ function Invitation() {
143119
error: queryError,
144120
refetch,
145121
} = useQuery(GET_ALL_INVITATIONS, {
122+
fetchPolicy: 'network-only',
146123
});
147124

148125
const [
149126
fetchInvitations,
150127
{ data: searchData, loading: searchLoading, error: searchError },
151-
] = useLazyQuery(GET_INVITATIONS);
128+
] = useLazyQuery(GET_INVITATIONS, {
129+
variables: {
130+
query: searchQuery,
131+
}, fetchPolicy: 'network-only',
132+
});
152133

153134
/* istanbul ignore next */
154135
const removeInviteeMod = () => {
155136
const newState = !removeInviteeModel;
156137
setRemoveInviteeModel(newState);
157138
};
158139

140+
const [
141+
filterInvitations,
142+
{ data: filterData, loading: filterLoad, error: filterError },
143+
] = useLazyQuery(GET_ROLES_AND_STATUSES, {
144+
variables: filterVariables,
145+
fetchPolicy: 'network-only',
146+
});
147+
148+
useEffect(() => {
149+
if (filterVariables.role || filterVariables.status) {
150+
filterInvitations();
151+
}
152+
}, [filterVariables, filterInvitations]);
153+
159154
useEffect(() => {
160-
if (queryLoading || searchLoading) {
155+
if (queryLoading || searchLoading || filterLoad) {
161156
setLoading(true);
162157
} else {
163158
setLoading(false);
@@ -167,18 +162,21 @@ function Invitation() {
167162
setError(queryError.message);
168163
} else if (searchError) {
169164
setError(searchError.message);
165+
} else if (filterError) {
166+
setError(filterError.message);
170167
} else if (
171168
searchData &&
172169
Array.isArray(searchData.getInvitations.invitations)
173170
) {
174-
refetch();
175171
setInvitations(searchData.getInvitations.invitations);
172+
} else if (filterData && filterData.filterInvitations) {
173+
setInvitations(filterData.filterInvitations.invitations);
174+
setTotalInvitations(filterData.filterInvitations.totalInvitations);
176175
} else if (data && data.getAllInvitations) {
177176
setInvitations(data.getAllInvitations.invitations);
178177
setTotalInvitations(data.getAllInvitations.totalInvitations);
179178
}
180-
refetch();
181-
}, [data, searchData, queryLoading, searchLoading, queryError, searchError]);
179+
}, [data, searchData, queryLoading, searchLoading, queryError, searchError, filterData, filterLoad, filterError]);
182180

183181
const handleSearch = () => {
184182
if (!searchQuery.trim()) {
@@ -190,13 +188,35 @@ function Invitation() {
190188
setError(null);
191189
setLoading(false);
192190

193-
fetchInvitations();
191+
fetchInvitations({
192+
variables: {
193+
query: searchQuery,
194+
},
195+
});
194196
};
195197

196198
const toggleOptions = (row: string) => {
197199
setSelectedRow(selectedRow === row ? null : row);
198200
}
199201

202+
const handleFilter = () => {
203+
if (!selectedRole && !selectedStatus) {
204+
toast.info('Please select role or status.');
205+
return;
206+
}
207+
208+
setInvitations([]);
209+
setError(null);
210+
setLoading(false);
211+
212+
setFilterVariables({
213+
role: selectedRole,
214+
status: selectedStatus,
215+
});
216+
};
217+
218+
const disabledSearch = !searchQuery.trim();
219+
200220
// Defining invitation table
201221
let content;
202222
const capitalizeStrings = (str: string): string => {
@@ -336,14 +356,14 @@ function Invitation() {
336356
});
337357
});
338358
}
339-
if (loading || searchLoading) {
359+
if (loading || searchLoading || filterLoad) {
340360
content = <DataTableStats
341361
data={invitations?.length > 0 ? datum : []}
342362
columns={columns}
343363
loading={loading}
344364
error={error}
345365
/>;
346-
} else if (error || searchError) {
366+
} else if (error || searchError || filterError) {
347367
content = <DataTableStats
348368
data={invitations?.length > 0 ? datum : []}
349369
columns={columns}
@@ -571,6 +591,7 @@ function Invitation() {
571591
</div>
572592
<button
573593
type="button"
594+
disabled={disabledSearch}
574595
onClick={handleSearch}
575596
className="bg-[#9e85f5] text-white text-lg md:text-xl rounded-md h-10 flex items-center justify-center md:w-[10%] p-0 sm:p-5 xm:p-5"
576597
>
@@ -579,8 +600,49 @@ function Invitation() {
579600
</div>
580601
</div>
581602

603+
<div className='mt-6'>
604+
<div className="flex flex-wrap items-center space-x-4 space-y-2 md:space-y-0">
605+
<p className="w-full md:w-auto">Or filter by <span><b>ROLE: </b></span></p>
606+
<span className="w-full md:w-auto">
607+
<select
608+
className="w-full max-w-xs md:w-auto dark:text-white dark:text:text-white bg-transparent text-gray-700 outline-none border border-gray-300 rounded px-2 py-1"
609+
value={selectedRole}
610+
onChange={(e) => setSelectedRole(e.target.value)}
611+
>
612+
<option value="">-</option>
613+
<option value="trainee">trainee</option>
614+
<option value="ttl">ttl</option>
615+
<option value="coordinator">coordinator</option>
616+
<option value="manager">manager</option>
617+
<option value="admin">admin</option>
618+
</select>
619+
</span>
620+
<span className="w-full md:w-auto"> or <b>STATUS: </b></span>
621+
<span className="w-full md:w-auto">
622+
<select
623+
className="w-full max-w-xs md:w-auto dark:text-white bg-transparent text-gray-700 outline-none border border-gray-300 rounded px-2 py-1"
624+
value={selectedStatus}
625+
onChange={(e) => setSelectedStatus(e.target.value)}
626+
>
627+
<option value="">-</option>
628+
<option value="pending">pending</option>
629+
<option value="accepted">accepted</option>
630+
<option value="denied">denied</option>
631+
<option value="cancelled">cancelled</option>
632+
</select>
633+
</span>
634+
<button
635+
type="button"
636+
// disabled={disabled}
637+
onClick={handleFilter}
638+
className="w-full max-w-xs md:w-auto bg-[#9e85f5] text-white text-lg md:text-xl rounded-md h-10 flex items-center justify-center px-4 py-2"
639+
>
640+
Filter
641+
</button>
642+
</div>
582643
{/* Table view */}
583644
{content}
645+
</div>
584646

585647
{/* =========================== Start:: DeleteInvitee Model =============================== */}
586648

src/queries/invitation.queries.tsx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { gql } from "@apollo/client";
2+
3+
4+
export const GET_ALL_INVITATIONS = gql`
5+
query AllInvitations($limit: Int, $offset: Int) {
6+
getAllInvitations(limit: $limit, offset: $offset) {
7+
invitations {
8+
invitees {
9+
email
10+
role
11+
}
12+
id
13+
status
14+
}
15+
totalInvitations
16+
}
17+
}
18+
`;
19+
20+
export const GET_INVITATIONS = gql`
21+
query GetInvitations($query: String!, $limit: Int, $offset: Int) {
22+
getInvitations(query: $query, limit: $limit, offset: $offset) {
23+
invitations {
24+
invitees {
25+
email
26+
role
27+
}
28+
id
29+
status
30+
}
31+
}
32+
}
33+
`;
34+
35+
export const GET_ROLES_AND_STATUSES = gql`
36+
query filterInvitations($limit: Int, $offset: Int, $role: String, $status: String) {
37+
filterInvitations(limit: $limit, offset: $offset, role: $role, status: $status) {
38+
invitations {
39+
invitees {
40+
email
41+
role
42+
}
43+
id
44+
status
45+
}
46+
}
47+
}
48+
`;

0 commit comments

Comments
 (0)