diff --git a/src/routes/admin/cohorts/ViewCohort.tsx b/src/routes/admin/cohorts/ViewCohort.tsx index a5125dd..9b77050 100644 --- a/src/routes/admin/cohorts/ViewCohort.tsx +++ b/src/routes/admin/cohorts/ViewCohort.tsx @@ -48,7 +48,7 @@ interface State { selectedWindow: (Omit & { id: number | null }) | null; } -const mockExcuses = [ +const mockExcuses: ExcuseBase[] = [ { id: 1, user: { @@ -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, @@ -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 => { const [state, setState] = useReducer( @@ -354,6 +368,7 @@ export const ViewCohort = (): ReactElement => { id} + windows={cohort.windows} /> { + 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', @@ -30,10 +52,37 @@ const getColumns = (onView: (id: number) => void): TableColumn[] => { customSortComparator: compareNamesAscending, }, }, + { + label: 'Window', + key: 'window', + options: { + customBodyRenderer: (window: WindowBase): ReactNode => ( + {`Window ${getWindowNumber(window)}`} + ), + 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 ( + + {tags.map((tag) => ( + + {tag} + + ))} + + ); + }, isSortable: true, }, }, @@ -42,7 +91,7 @@ const getColumns = (onView: (id: number) => void): TableColumn[] => { key: 'reason', options: { customBodyRenderer: (reason: string): ReactNode => ( -
+
{reason}
), @@ -53,6 +102,19 @@ const getColumns = (onView: (id: number) => void): TableColumn[] => { label: 'Status', key: 'status', options: { + customBodyRenderer: (status: ExcuseStatus): ReactNode => ( + + {status} + + ), isSortable: true, }, }, @@ -76,8 +138,41 @@ const getColumns = (onView: (id: number) => void): TableColumn[] => { export const ExcuseTable = ({ excuses, onView, + windows, }: Props): ReactElement => { - 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 ( @@ -85,10 +180,13 @@ export const ExcuseTable = ({ actionButton={ - setFilter(e.target.value)} + value={filter} + > - + @@ -99,7 +197,7 @@ export const ExcuseTable = ({ isDownloadable: false, numRowsPerPage: excuses.length, }} - rows={excuses} + rows={filteredExcuses} /> );