mirror of
https://github.com/sergeyyarkov/educt-client.git
synced 2026-10-11 10:19:22 +03:00
136 lines
4.1 KiB
TypeScript
136 lines
4.1 KiB
TypeScript
import React from 'react';
|
|
import { Table, Tbody, Button, Input, InputGroup, InputLeftElement, Flex, Box, Text } from '@chakra-ui/react';
|
|
import { MdSearch } from 'react-icons/md';
|
|
|
|
import AddStudentsModal from '@educt/components/Modals/AddStudentsModal';
|
|
import { AddButton } from '@educt/components/Buttons';
|
|
import BulkActionsMenu from './BulkActionsMenu';
|
|
import StudentTableHead from './StudentTableHead';
|
|
|
|
/**
|
|
* Types
|
|
*/
|
|
import type { StudentTableRowPropsType } from './StudentTableRow';
|
|
import type { ICourse } from '@educt/interfaces';
|
|
|
|
/**
|
|
* Hooks
|
|
*/
|
|
import { useCallback, useState } from 'react';
|
|
import { useDisclosure } from '@chakra-ui/react';
|
|
|
|
type StudentTableListPropsType = {
|
|
render: React.FC<StudentTableRowPropsType>;
|
|
course: Omit<ICourse, 'students_count' | 'likes_count' | 'lessons_count'>;
|
|
};
|
|
|
|
const StudentTableList: React.FC<StudentTableListPropsType> = props => {
|
|
const { render: Row, course } = props;
|
|
const { students } = course;
|
|
|
|
const [rows, setRows] = useState<ICourse['students']>(students);
|
|
const [selected, setSelected] = useState<ICourse['students']>([]);
|
|
const [search, setSearch] = useState<string>('');
|
|
const {
|
|
isOpen: isOpenAddStudentModal,
|
|
onOpen: onOpenAddStudentModal,
|
|
onClose: onCloseAddStudentModal,
|
|
} = useDisclosure();
|
|
|
|
/**
|
|
* Search for a student by input
|
|
*/
|
|
const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
setSearch(e.target.value);
|
|
setRows([
|
|
...students.filter(
|
|
s => s.fullname.toLowerCase().includes(e.target.value) || s.email.toLowerCase().includes(e.target.value)
|
|
),
|
|
]);
|
|
};
|
|
|
|
/**
|
|
* Select all students in a table
|
|
*/
|
|
const handleSelectAll = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
if (e.target.checked) {
|
|
setSelected(rows);
|
|
return;
|
|
}
|
|
|
|
setSelected([]);
|
|
};
|
|
|
|
/**
|
|
* Select a student with checkbox
|
|
*/
|
|
const handleSelect = useCallback((e: React.ChangeEvent<HTMLInputElement>, student: ICourse['students'][number]) => {
|
|
if (e.target.checked) {
|
|
setSelected(prev => [...prev, student]);
|
|
return;
|
|
}
|
|
|
|
setSelected(prev => prev.filter(s => s.id !== student.id));
|
|
}, []);
|
|
|
|
if (rows.length === 0) {
|
|
return (
|
|
<>
|
|
<AddStudentsModal isOpen={isOpenAddStudentModal} onClose={onCloseAddStudentModal} courseId={course.id} />
|
|
<Box textAlign='center' mt='10'>
|
|
<Text>There are no students in the course yet</Text>
|
|
<Button mt='2' onClick={onOpenAddStudentModal} size='sm' colorScheme='blue' variant='outline'>
|
|
Add student
|
|
</Button>
|
|
</Box>
|
|
</>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<Box>
|
|
<AddStudentsModal isOpen={isOpenAddStudentModal} onClose={onCloseAddStudentModal} courseId={course.id} />
|
|
<Flex justifyContent='space-between' flexDir={{ base: 'column', lg: 'row' }}>
|
|
<Flex mb='2'>
|
|
<InputGroup mr='2' borderRadius='lg'>
|
|
<InputLeftElement pointerEvents='none'>
|
|
<MdSearch color='gray.300' />
|
|
</InputLeftElement>
|
|
<Input value={search} size='sm' onChange={handleSearch} type='text' placeholder='Search for student...' />
|
|
</InputGroup>
|
|
</Flex>
|
|
|
|
<Flex alignItems='center' justifyContent='space-between' pr={{ base: '8px', lg: '0' }}>
|
|
{selected.length !== 0 && (
|
|
<>
|
|
<Text mr='4'>
|
|
You have selected <b>{selected.length}</b> student(s).
|
|
</Text>
|
|
<BulkActionsMenu selected={selected} rows={rows} setRows={setRows} />
|
|
</>
|
|
)}
|
|
<AddButton onClick={onOpenAddStudentModal} />
|
|
</Flex>
|
|
</Flex>
|
|
<Table overflow='hidden' borderRadius='lg' mt='2'>
|
|
<StudentTableHead onSelectAll={handleSelectAll} />
|
|
<Tbody>
|
|
{rows.map(student => (
|
|
<Row
|
|
key={student.id}
|
|
student={student}
|
|
isSelected={!!selected.find(s => s.id === student.id)}
|
|
onSelect={handleSelect}
|
|
/>
|
|
))}
|
|
</Tbody>
|
|
</Table>
|
|
<Text mt='4' fontSize='sm' color='gray.500'>
|
|
{students.length} student(s)
|
|
</Text>
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
export default StudentTableList;
|