Skip to content

Commit

Permalink
#504 fixing teams cards (#545)
Browse files Browse the repository at this point in the history
* fixing teams cards

* fixing teams cards

---------

Co-authored-by: Igor IHIMBAZWE <[email protected]>
  • Loading branch information
2 people authored and niyobertin committed Oct 7, 2024
1 parent 8448da6 commit e9f7ee5
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 115 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions src/Skeletons/SkeletonTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* eslint-disable react/no-array-index-key */
/* eslint-disable react/prop-types */
import React from 'react';

interface SkeletonTableProps {
columns: Array<any>;
}

function SkeletonTable({ columns }: SkeletonTableProps) {
return (
<table className="min-w-full leading-normal">
<thead>
<tr>
{columns.map((column: any, index: React.Key | null | undefined) => (
<th key={index} className="px-6 py-3 border-b-2 border-gray-200 bg-gray-100 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">

Check failure on line 15 in src/Skeletons/SkeletonTable.tsx

View workflow job for this annotation

GitHub Actions / build

A control must be associated with a text label
<div className="h-4 bg-gray-300 rounded w-3/4"></div>
</th>
))}
</tr>
</thead>
<tbody>
{[...Array(5)].map((_, rowIndex) => (
<tr key={rowIndex}>
{columns.map((_, colIndex) => (
<td key={colIndex} className="px-6 py-4 border-b border-gray-200 bg-white text-sm">
<div className="h-4 bg-gray-300 rounded w-full"></div>
</td>
))}
</tr>
))}
</tbody>
</table>
);
}

export default SkeletonTable;
21 changes: 17 additions & 4 deletions src/components/CoordinatorCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,14 @@ export const GET_TEAMS_CARDS = gql`
professional_Skills
}
members {
id
profile {
name
lastName
firstName
}
status{
status
}
}
active
Expand Down Expand Up @@ -141,6 +147,13 @@ function ManagerCard() {
rating = 'text-red-700';
}

const activeMembers = team.members.filter(
(member: any) => member.status?.status === 'active'
).length;
const droppedMembers = team.members.filter(
(member: any) => member.status?.status === 'drop'
).length;

return {
stylebg,
stylebg1,
Expand All @@ -159,16 +172,16 @@ function ManagerCard() {
skills,
Qty,
Qnty,
active: team?.members.length,
drop: 0,
active: activeMembers,
drop: droppedMembers,
};
});

return (
<div className="px-4 md:px-0 pb-20 w-full dark:bg-dark-frame-bg dark:text-black h-full flex overflow-x-auto ">
{loading ? (
<div className="flex items-center justify-center w-full h-full">
<div className="spinner" />
<div className="spinner" data-testid="spinner" />
</div>
) : (
<div className="pl-10 flex">
Expand All @@ -184,4 +197,4 @@ function ManagerCard() {
);
}

export default ManagerCard;
export default ManagerCard;
183 changes: 84 additions & 99 deletions src/components/InvitationTable.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
// @ts-nocheck
import React, { useState,useEffect, useMemo } from 'react';
import React, { useState, useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import {
useGlobalFilter,
usePagination,
useSortBy,
useTable,
} from 'react-table';
import { useGlobalFilter, usePagination, useSortBy, useTable } from 'react-table';
import { toast } from 'react-toastify';
import DataPagination from './DataPagination';
import SkeletonTable from '../Skeletons/SkeletonTable';

interface TableData {
data: any[];
Expand All @@ -31,7 +28,7 @@ function DataTableStats({ data, columns, error, loading }: TableData) {
{
data: memoizedData,
columns: memoizedColumns,
initialState: {pageIndex, pageSize: 3, globalFilter: filterInput },
initialState: { pageIndex, pageSize: 3, globalFilter: filterInput },
},
useGlobalFilter,
useSortBy,
Expand All @@ -55,10 +52,17 @@ function DataTableStats({ data, columns, error, loading }: TableData) {
prepareRow,
state: { pageIndex: currentPageIndex, pageSize },
} = tableInstance;

useEffect(() => {
setPageIndex(currentPageIndex);
}, [currentPageIndex]);

useEffect(() => {
if (error) {
toast.error('Network error. Please, try again later.');
}
}, [error]);

const handleFilterChange = (e) => {
const value = e.target.value || '';
setGlobalFilter(value);
Expand All @@ -69,96 +73,77 @@ function DataTableStats({ data, columns, error, loading }: TableData) {
<div className="">
<div className="flex items-center justify-between pb-6 " />
<div style={{ overflowX: 'auto' }}>
<table className="min-w-full leading-normal" {...getTableProps()}>
<thead>
{headerGroups.map((headerGroup) => (
<tr key={headerGroup.id} {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th
key={column.id}
className={column.isSorted ? 'sort-asc thead' : ' thead'}
{...column.getHeaderProps(column.getSortByToggleProps())}
>
{column.render('Header')}
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{!loading && memoizedData.length === 0 ? (
<tr>
<td
colSpan={columns.length}
className="px-6 py-4 text-sm text-center text-gray-500 dark:text-gray-300"
aria-label="Empty cell" // Added for accessibility
>
&nbsp;{' '}
{/* Non-breaking space to ensure it's not an empty tag */}
</td>
</tr>
) : (
page.map((row) => {
prepareRow(row);
return (
<tr
key={row.id}
className={`border-b dark:border-gray-700 ${
row.index % 2 === 0
? 'bg-light-bg dark:bg-neutral-600'
: 'bg-white dark:bg-dark-bg'
}`}
{...row.getRowProps()}
{loading ? (
<SkeletonTable columns={columns} />
) : (
<table className="min-w-full leading-normal" {...getTableProps()}>
<thead>
{headerGroups.map((headerGroup) => (
<tr key={headerGroup.id} {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th
key={column.id}
className={column.isSorted ? 'sort-asc thead' : ' thead'}
{...column.getHeaderProps(column.getSortByToggleProps())}
>
{column.render('Header')}
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{memoizedData.length === 0 && (
<tr>
<td
colSpan={columns.length}
className="px-6 py-4 text-sm text-center text-gray-500 dark:text-gray-300"
aria-label="Empty cell" // Added for accessibility
>
{row.cells.map((cell) => (
<td
key={cell.id}
className="data-cell "
{...cell.getCellProps()}
>
{cell.render('Cell')}
</td>
))}
</tr>
);
})
)}
{loading && (
<tr>
<td
colSpan={columns.length}
className="px-6 py-4 text-sm text-center text-gray-500 dark:text-gray-300 "
>
Loading...
</td>
</tr>
)}
{error && (
<tr>
<td
colSpan={columns.length}
className="px-6 py-4 text-sm text-center text-gray-500 dark:text-gray-300 "
>
Error occurred
</td>
</tr>
)}
{!loading && !error && data.length === 0 && (
<tr>
{' '}
<td colSpan={columns.length || 100} className="text-center p-4">
<div className="flex flex-col items-center justify-center space-y-4">
{' '}
<p className="text-gray-600 dark:text-gray-400 text-lg font-medium">
{' '}
No records available{' '}
</p>
</div>{' '}
</td>{' '}
</tr>
)}
</tbody>
</table>
&nbsp;{' '}
{/* Non-breaking space to ensure it's not an empty tag */}
</td>
</tr>
)}
{memoizedData.length > 0 &&
page.map((row) => {
prepareRow(row);
return (
<tr
key={row.id}
className={`border-b dark:border-gray-700 ${
row.index % 2 === 0
? 'bg-light-bg dark:bg-neutral-600'
: 'bg-white dark:bg-dark-bg'
}`}
{...row.getRowProps()}
>
{row.cells.map((cell) => (
<td
key={cell.id}
className="data-cell "
{...cell.getCellProps()}
>
{cell.render('Cell')}
</td>
))}
</tr>
);
})}
{!loading && !error && data.length === 0 && (
<tr>
<td colSpan={columns.length || 100} className="text-center p-4">
<div className="flex flex-col items-center justify-center space-y-4">
<p className="text-gray-600 dark:text-gray-400 text-lg font-medium">
No records available
</p>
</div>
</td>
</tr>
)}
</tbody>
</table>
)}
</div>
<div className="px-6 py-4">
<DataPagination
Expand All @@ -179,4 +164,4 @@ function DataTableStats({ data, columns, error, loading }: TableData) {
);
}

export default DataTableStats;
export default DataTableStats;
15 changes: 12 additions & 3 deletions src/components/ManagerCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ export const GET_TEAMS_CARDS = gql`
profile {
name
}
status{
status
}
}
active
startingPhase
Expand Down Expand Up @@ -136,6 +139,12 @@ function ManagerCard() {
stylebg1 = 'bg-red-400 text-red-700';
rating = 'text-red-700';
}
const activeMembers = team.members.filter(
(member: any) => member.status?.status === 'active'
).length;
const droppedMembers = team.members.filter(
(member: any) => member.status?.status === 'drop'
).length;

return {
stylebg,
Expand All @@ -155,8 +164,8 @@ function ManagerCard() {
skills,
Qty,
Qnty,
active: team?.members.length,
drop: 0,
active: activeMembers,
drop: droppedMembers,
};
});

Expand All @@ -180,4 +189,4 @@ function ManagerCard() {
);
}

export default ManagerCard;
export default ManagerCard;
2 changes: 1 addition & 1 deletion src/components/Notification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ function Notification({
if (user.role === 'admin') {
navigate('/teams');
} else {
navigate('/cards');
navigate('/teams/cards');
}
} else if (notification.type === 'cohort') {
navigate('/cohorts');
Expand Down
4 changes: 2 additions & 2 deletions src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ function Sidebar({ style, toggle }: { style: string; toggle: () => void }) {
{/* FOR COORDINATORS */}
<CheckRole roles={['coordinator']}>
{/* team cards */}
<SideNavLink onClick={toggle} name="Teams" to="/cards">
<SideNavLink onClick={toggle} name="Teams" to="/teams/cards">
<UserGroupIcon className="w-5 " />
</SideNavLink>

Expand Down Expand Up @@ -196,4 +196,4 @@ function Sidebar({ style, toggle }: { style: string; toggle: () => void }) {
);
}

export default Sidebar;
export default Sidebar;
Loading

0 comments on commit e9f7ee5

Please sign in to comment.