Skip to content

Commit caa9a76

Browse files
committed
fix(fix bug on table)
- displaying 3 dotted button - modal responsiveness [Delivers #500]
1 parent deee499 commit caa9a76

File tree

3 files changed

+528
-94
lines changed

3 files changed

+528
-94
lines changed

src/components/InvitationTable.tsx

Lines changed: 214 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// @ts-nocheck
2-
import React, { useState, useMemo } from 'react';
2+
import React, { useState, useEffect, useRef, useMemo } from 'react';
33
import { useTranslation } from 'react-i18next';
44
import {
55
useGlobalFilter,
@@ -16,8 +16,14 @@ interface TableData {
1616
loading?: boolean;
1717
className?: string;
1818
}
19+
import Button from '../components/Buttons';
20+
import { Icon } from '@iconify/react';
21+
import { useMutation } from '@apollo/client';
22+
import { DELETE_INVITATION } from '../Mutations/invitationMutation';
23+
import { toast } from 'react-toastify';
1924

2025
function DataTableStats({ data, columns, error, loading }: TableData) {
26+
2127
const [filterInput, setFilterInput] = useState('');
2228
const { t } = useTranslation();
2329

@@ -55,12 +61,73 @@ function DataTableStats({ data, columns, error, loading }: TableData) {
5561
state: { pageIndex, pageSize },
5662
} = tableInstance;
5763

58-
const handleFilterChange = (e) => {
64+
const handleFilterChange = (e:any) => {
5965
const value = e.target.value || '';
6066
setGlobalFilter(value);
6167
setFilterInput(value);
6268
};
69+
const [selectedRow, setSelectedRow] = useState(null);
70+
const [openUpwards, setOpenUpwards] = useState(false);
71+
const [removeInviteeModel, setRemoveInviteeModel] = useState(false);
72+
const [deleteInvitation, setDeleteInvitation] = useState('');
73+
const [buttonLoading, setButtonLoading] = useState(false);
74+
const modalRef = useRef(null);
75+
/* istanbul ignore next */
76+
const removeInviteeMod = () => {
77+
const newState = !removeInviteeModel;
78+
setRemoveInviteeModel(newState);
79+
};
80+
// Toggle modal and check if it should open upwards
81+
const toggleOptions = (rowId:any, rowRef:any) => {
82+
if (selectedRow === rowId) {
83+
setSelectedRow(null);
84+
} else {
85+
setSelectedRow(rowId);
6386

87+
// Calculate if it should open upwards
88+
const rowPosition = rowRef.current.getBoundingClientRect();
89+
const spaceBelow = window.innerHeight - rowPosition.bottom;
90+
console.log('bbb2', window.innerHeight)
91+
console.log('bbb3', rowPosition.bottom)
92+
console.log('bbb', spaceBelow)
93+
setOpenUpwards(spaceBelow < 230); // Adjust this threshold as needed
94+
}
95+
};
96+
97+
// Close modal when clicking outside
98+
useEffect(() => {
99+
const handleClickOutside = (event: any) => {
100+
console.log(modalRef)
101+
if (modalRef.current && !modalRef.current.contains(event.target)) {
102+
setSelectedRow(null);
103+
}
104+
};
105+
document.addEventListener('mousedown', handleClickOutside);
106+
return () => {
107+
document.removeEventListener('mousedown', handleClickOutside);
108+
};
109+
}, [modalRef]);
110+
const [DeleteInvitation] = useMutation(
111+
DELETE_INVITATION,
112+
{
113+
variables: {
114+
invitationId: deleteInvitation,
115+
},
116+
onCompleted: (data) => {
117+
setTimeout(() => {
118+
setButtonLoading(false);
119+
toast.success(data.deleteInvitation.message);
120+
removeInviteeMod();
121+
}, 1000);
122+
},
123+
onError: (err) => {
124+
setTimeout(() => {
125+
setButtonLoading(false);
126+
toast.error(err.message);
127+
}, 500);
128+
},
129+
},
130+
);
64131
return (
65132
<div
66133
className={``}
@@ -76,7 +143,7 @@ function DataTableStats({ data, columns, error, loading }: TableData) {
76143
<th
77144
key={column.id}
78145
className={column.isSorted ? 'sort-asc thead' : ' thead'}
79-
{...column.getHeaderProps(column.getSortByToggleProps())}
146+
{...column.getHeaderProps(column)}
80147
>
81148
{column.render('Header')}
82149
</th>
@@ -99,6 +166,7 @@ function DataTableStats({ data, columns, error, loading }: TableData) {
99166
) : (
100167
page.map((row) => {
101168
prepareRow(row);
169+
const rowRef = useRef(null);
102170
return (
103171
<tr
104172
key={row.id}
@@ -108,14 +176,99 @@ function DataTableStats({ data, columns, error, loading }: TableData) {
108176
: 'bg-white dark:bg-dark-bg'
109177
}`}
110178
{...row.getRowProps()}
179+
ref={rowRef}
111180
>
112181
{row.cells.map((cell) => (
113182
<td
114183
key={cell.id}
115184
className="data-cell "
116185
{...cell.getCellProps()}
117-
>
118-
{cell.render('Cell')}
186+
> {cell.column.id === 'actions' ? (
187+
<div className="static">
188+
<div className="static inline-block">
189+
<Icon
190+
icon="entypo:dots-three-vertical"
191+
width="25"
192+
cursor="pointer"
193+
color="#9e85f5"
194+
onClick={() => toggleOptions(row.id, rowRef)}
195+
/>
196+
{selectedRow === row.id && (
197+
<div
198+
ref={modalRef}
199+
className={`dropdown absolute right-4 mt-2 w-64 bg-light-bg max-h-30 dark:bg-dark-bg border border-gray-300 shadow-md z-50 p-4 rounded-lg overflow-hidden ${
200+
openUpwards ? 'bottom-5' : ''
201+
}`}>
202+
<>
203+
<div className="mb-4"></div>
204+
<div className="mb-4">
205+
<div className="flex items-center hover:bg-gray-100 dark:hover:bg-gray-800 p-2 rounded-md cursor-pointer">
206+
<Icon
207+
icon="el:file-edit-alt"
208+
className="mr-2"
209+
width="38"
210+
height="38"
211+
cursor="pointer"
212+
color="#9e85f5"
213+
/>
214+
<div>
215+
<span className="font-bold">Update</span>
216+
<br />
217+
Update invitation
218+
</div>
219+
</div>
220+
</div>
221+
<div className="mb-4">
222+
<div
223+
className="flex items-center hover:bg-gray-100 dark:hover:bg-gray-800 p-2 rounded-md cursor-pointer"
224+
onClick={() => {
225+
// Custom logic for deleting
226+
removeInviteeMod();
227+
setDeleteInvitation(row.original.id);
228+
toggleOptions(row.original.email, rowRef);
229+
}}
230+
>
231+
<Icon
232+
icon="mdi:close-circle-outline"
233+
width="40"
234+
height="40"
235+
cursor="pointer"
236+
color="#9e85f5"
237+
/>
238+
<div>
239+
<span className="font-bold">Delete</span>
240+
<br />
241+
Delete invitation
242+
</div>
243+
</div>
244+
</div>
245+
{row.original.Status === 'Pending' && (
246+
<div className="mb-4">
247+
<div className="flex items-center hover:bg-gray-100 dark:hover:bg-gray-800 p-2 rounded-md cursor-pointer">
248+
<Icon
249+
icon="mdi:arrow-up-circle"
250+
width="40"
251+
height="40"
252+
cursor="pointer"
253+
color="#9e85f5"
254+
/>
255+
<div>
256+
<span className="font-bold">Resend</span>
257+
<br />
258+
Resend invitation
259+
</div>
260+
</div>
261+
</div>
262+
)}
263+
</>
264+
</div>
265+
)}
266+
</div>
267+
</div>
268+
) : (
269+
cell.render('Cell')
270+
)}
271+
{/* {cell.render('Cell')} */}
119272
</td>
120273
))}
121274
</tr>
@@ -173,6 +326,62 @@ function DataTableStats({ data, columns, error, loading }: TableData) {
173326
pageCount={pageCount}
174327
pageIndex={pageIndex}
175328
/>
329+
</div>
330+
{/* =========================== Start:: DeleteInvitee Model =============================== */}
331+
332+
<div
333+
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 ${
334+
removeInviteeModel === true ? 'block' : 'hidden'
335+
}`}
336+
>
337+
<div className="w-full p-4 pb-8 bg-white rounded-lg dark:bg-dark-bg sm:w-3/4 xl:w-4/12">
338+
<div className="flex flex-wrap items-center justify-center w-full card-title ">
339+
<h3 className="w-11/12 text-sm font-bold text-center dark:text-white ">
340+
{t('Delete Invitation')}
341+
</h3>
342+
<hr className="w-full my-3 border-b bg-primary" />
343+
</div>
344+
<div className="card-body">
345+
<form className="px-8 py-3 ">
346+
<div className="flex flex-wrap items-center justify-center w-full card-title ">
347+
<h3 className="w-11/12 text-sm font-bold text-center dark:text-white ">
348+
{t(
349+
'Are you sure you want to Delete this invitation?',
350+
)}
351+
</h3>
352+
</div>
353+
354+
<div className="flex justify-between w-full">
355+
<Button
356+
data-testid="removeModel2"
357+
variant="info"
358+
size="sm"
359+
style="w-[40%] md:w-1/4 text-sm font-sans"
360+
onClick={() => removeInviteeMod()}
361+
>
362+
{t('Cancel')}
363+
</Button>
364+
<Button
365+
variant="primary"
366+
size="sm"
367+
data-testid="removeMemberFromCohort"
368+
style="w-[40%] md:w-1/4 text-sm font-sans"
369+
onClick={() => {
370+
setButtonLoading(true);
371+
if (deleteInvitation) {
372+
DeleteInvitation();
373+
} else {
374+
toast.error('Please select the trainee again ');
375+
}
376+
}}
377+
loading={buttonLoading}
378+
>
379+
{t('Proceed')}
380+
</Button>
381+
</div>
382+
</form>
383+
</div>
384+
</div>
176385
</div>
177386
</div>
178387
);

0 commit comments

Comments
 (0)