Skip to content

Commit

Permalink
feat: add ui changes to admin table + add filter condition
Browse files Browse the repository at this point in the history
  • Loading branch information
ShenyiCui committed Jun 10, 2024
1 parent 0cf99a3 commit ff2dbd2
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 11 deletions.
19 changes: 17 additions & 2 deletions src/routes/admin/cohorts/ViewCohort.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ interface State {
selectedWindow: (Omit<WindowBase, 'id'> & { id: number | null }) | null;
}

const mockExcuses = [
const mockExcuses: ExcuseBase[] = [
{
id: 1,
user: {
Expand All @@ -58,6 +58,13 @@ const mockExcuses = [
photoUrl:
'https://res.cloudinary.com/folio-hnr/image/upload/v1679629122/blob_ycezgh.jpg',
},
window: {
id: 1,
startAt: new Date('2022-01-01'),
endAt: new Date('2022-01-07'),
numQuestions: 6,
requireInterview: true,
},
excuseFrom: ExcuseFrom.INTERVIEW_AND_QUESTION,
reason: 'I am sick',
status: ExcuseStatus.PENDING,
Expand All @@ -70,12 +77,19 @@ const mockExcuses = [
profileUrl: 'https://github.com',
photoUrl: 'https://avatars.githubusercontent.com/u/29945147?v=4',
},
window: {
id: 2,
startAt: new Date('2022-01-08'),
endAt: new Date('2022-01-14'),
numQuestions: 6,
requireInterview: true,
},
excuseFrom: ExcuseFrom.QUESTION,
reason:
'I am going on a holiday really far away, this is a super long piece of text that should be truncated at some point in time',
status: ExcuseStatus.REJECTED,
},
] as ExcuseBase[];
];

export const ViewCohort = (): ReactElement<void, typeof ViewCohortPage> => {
const [state, setState] = useReducer(
Expand Down Expand Up @@ -354,6 +368,7 @@ export const ViewCohort = (): ReactElement<void, typeof ViewCohortPage> => {
<ExcuseTable
excuses={mockExcuses}
onView={(id: number): number => id}
windows={cohort.windows}
/>
</Stack>
<ConfirmRematchWindows
Expand Down
116 changes: 107 additions & 9 deletions src/routes/admin/cohorts/tables/ExcuseTable.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,43 @@
import { ReactElement, ReactNode, useMemo } from 'react';
import { ReactElement, ReactNode, useCallback, useMemo, useState } from 'react';
import { HiFilter } from 'react-icons/hi';
import { Button, HStack, Select, Text } from '@chakra-ui/react';
import { Button, HStack, Select, Tag, Text } from '@chakra-ui/react';

import { Card } from '@/components/card';
import { Table } from '@/components/table';
import { UserProfile } from '@/components/userProfile';
import { ExcuseBase } from '@/types/api/excuses';
import { UserBase } from '@/types/api/users';
import { WindowBase } from '@/types/api/windows';
import { ExcuseFrom, ExcuseStatus } from '@/types/models/excuse';
import { TableColumn } from '@/types/table';
import { compareNamesAscending } from '@/utils/sortUtils';
import {
compareDatesAscending,
compareNamesAscending,
} from '@/utils/sortUtils';

const getExcuseFromTags = (e: ExcuseFrom): string[] => {
switch (e) {
case ExcuseFrom.QUESTION:
return ['QUESTION'];
case ExcuseFrom.INTERVIEW:
return ['INTERVIEW'];
case ExcuseFrom.INTERVIEW_AND_QUESTION:
return ['QUESTION', 'INTERVIEW'];
default:
return [];
}
};

interface Props {
excuses: ExcuseBase[];
windows: WindowBase[];
onView: (id: number) => void;
}

const getColumns = (onView: (id: number) => void): TableColumn[] => {
const getColumns = (
onView: (id: number) => void,
getWindowNumber: (w: WindowBase) => number,
): TableColumn[] => {
return [
{
label: 'User',
Expand All @@ -30,10 +52,37 @@ const getColumns = (onView: (id: number) => void): TableColumn[] => {
customSortComparator: compareNamesAscending,
},
},
{
label: 'Window',
key: 'window',
options: {
customBodyRenderer: (window: WindowBase): ReactNode => (
<Text>{`Window ${getWindowNumber(window)}`}</Text>
),
isSortable: true,
customSortComparator: (a, b) =>
compareDatesAscending(a.startAt, b.startAt),
},
},
{
label: 'Excuse From',
key: 'excuseFrom',
options: {
customBodyRenderer: (excuseFrom: ExcuseFrom): ReactNode => {
const tags = getExcuseFromTags(excuseFrom);
return (
<HStack spacing={2}>
{tags.map((tag) => (
<Tag
colorScheme={tag === ExcuseFrom.QUESTION ? 'gray' : 'purple'}
key={tag}
>
{tag}
</Tag>
))}
</HStack>
);
},
isSortable: true,
},
},
Expand All @@ -42,7 +91,7 @@ const getColumns = (onView: (id: number) => void): TableColumn[] => {
key: 'reason',
options: {
customBodyRenderer: (reason: string): ReactNode => (
<div style={{ maxWidth: '225px' }}>
<div style={{ maxWidth: '150px' }}>
<Text isTruncated={true}>{reason}</Text>
</div>
),
Expand All @@ -53,6 +102,19 @@ const getColumns = (onView: (id: number) => void): TableColumn[] => {
label: 'Status',
key: 'status',
options: {
customBodyRenderer: (status: ExcuseStatus): ReactNode => (
<Tag
colorScheme={
status === ExcuseStatus.PENDING
? 'gray'
: status === ExcuseStatus.ACCEPTED
? 'green'
: 'red'
}
>
{status}
</Tag>
),
isSortable: true,
},
},
Expand All @@ -76,19 +138,55 @@ const getColumns = (onView: (id: number) => void): TableColumn[] => {
export const ExcuseTable = ({
excuses,
onView,
windows,
}: Props): ReactElement<Props, typeof Card> => {
const columns = useMemo(() => getColumns(onView), [onView]);
const [filter, setFilter] = useState('all');
const filteredExcuses = excuses.filter((excuse) => {
switch (filter) {
case 'pending':
return excuse.status === ExcuseStatus.PENDING;
case 'accepted':
return excuse.status === ExcuseStatus.ACCEPTED;
case 'rejected':
return excuse.status === ExcuseStatus.REJECTED;
default:
return true;
}
});

const sortedWindows = useMemo(
() =>
structuredClone(windows).sort((a, b) =>
compareDatesAscending(a.startAt, b.startAt),
),
[windows],
);

const getWindowNumber = useCallback(
(window: WindowBase): number => {
return sortedWindows.findIndex((w: WindowBase) => w.id === window.id) + 1;
},
[sortedWindows],
);

const columns = useMemo(
() => getColumns(onView, getWindowNumber),
[getWindowNumber, onView],
);

return (
<Card px={0} py={0}>
<Table
actionButton={
<HStack spacing={2}>
<HiFilter size={25} />
<Select>
<Select
onChange={(e): void => setFilter(e.target.value)}
value={filter}
>
<option value="all">All</option>
<option value="pending">Pending Decision</option>
<option value="approved">Approved</option>
<option value="accepted">Accepted</option>
<option value="rejected">Rejected</option>
</Select>
</HStack>
Expand All @@ -99,7 +197,7 @@ export const ExcuseTable = ({
isDownloadable: false,
numRowsPerPage: excuses.length,
}}
rows={excuses}
rows={filteredExcuses}
/>
</Card>
);
Expand Down

0 comments on commit ff2dbd2

Please sign in to comment.