313 lines
18 KiB
JavaScript
313 lines
18 KiB
JavaScript
import React, { useState } from 'react';
|
|
import { NavLink } from 'react-router-dom';
|
|
import { Table, Row, Col, Nav, Tab, Button, Form, InputGroup, Spinner, Modal } from 'react-bootstrap';
|
|
import Select from 'react-select';
|
|
import useClasses from '../hooks/useClasses';
|
|
import ModalOperation from '../../../../components/ui/adminMessageModal/ModalOperation';
|
|
import TablePaginate from '../../../../components/ui/TablePaginate';
|
|
|
|
const ManageClasses = () => {
|
|
const {
|
|
classes,
|
|
freeStudent,
|
|
loading,
|
|
error,
|
|
formData,
|
|
show,
|
|
showAssign,
|
|
showLoader,
|
|
loaderState,
|
|
createClass,
|
|
editClass,
|
|
deleteClass,
|
|
assignStudentToClass,
|
|
handleFormChange,
|
|
assignStudentChange,
|
|
assignClassChange,
|
|
resetForm,
|
|
handleShow,
|
|
handleShowAssign,
|
|
handleClose,
|
|
handleCloseLoader,
|
|
|
|
page,
|
|
totalData,
|
|
totalPages,
|
|
setSearch,
|
|
handlePageChange,
|
|
handleLimitsChange,
|
|
handleSerachChange
|
|
} = useClasses();
|
|
|
|
if (error) {
|
|
return (<>{error}</>);
|
|
}
|
|
|
|
return (
|
|
<div className='admin-teachers'>
|
|
<div className="d-flex justify-content-between">
|
|
<h2 className='page-title strip'>Classes</h2>
|
|
<Button variant="outline-blue" type="button" className='py-2 bg-white' onClick={handleShowAssign}>
|
|
<i className="bi bi-person-fill-add me-2"></i>Assign Student to Class
|
|
</Button>
|
|
</div>
|
|
<p className='page-desc'>Description of Classes.</p>
|
|
<Tab.Container id="left-tabs-example" defaultActiveKey="detail" onSelect={resetForm}>
|
|
<Row className='mb-45'>
|
|
<Col xs={12}>
|
|
<Nav variant="pills" className='col-tabs'>
|
|
<Nav.Item>
|
|
<Nav.Link eventKey="detail">View Entries</Nav.Link>
|
|
</Nav.Item>
|
|
<Nav.Item>
|
|
<Nav.Link eventKey="create">Create Data</Nav.Link>
|
|
</Nav.Item>
|
|
</Nav>
|
|
</Col>
|
|
</Row>
|
|
<Row className='mb-45'>
|
|
<Col xs={12} className='col-tabs-content'>
|
|
<Tab.Content>
|
|
<Tab.Pane eventKey="detail">
|
|
<div className="cards">
|
|
<div className="cards-title">
|
|
<h4>Class List</h4>
|
|
</div>
|
|
<div className="cards-body">
|
|
<Form className="mb-3 d-flex align-items-strech" onSubmit={(e) => { e.preventDefault(); handleSerachChange(); }}>
|
|
<Form.Control type='search'
|
|
aria-label="Large"
|
|
aria-describedby="inputGroup-sizing-sm"
|
|
placeholder='Search'
|
|
className='table-input-search mb-0 me-2 rounded-3'
|
|
onChange={(e) => { setSearch(e.target.value); }}
|
|
/>
|
|
<Button type='submit' variant='blue rounded-3'>Search</Button>
|
|
</Form>
|
|
<Table hover>
|
|
<thead>
|
|
<tr>
|
|
<th>No</th>
|
|
<th>Class Name</th>
|
|
<th className='text-center'>Capacity</th>
|
|
<th className='text-center'>Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{loading?(
|
|
<tr>
|
|
<td colSpan={5} style={{height:"20vh"}}>
|
|
<Spinner animation="grow" variant="primary" />
|
|
<Spinner animation="grow" variant="secondary" />
|
|
<Spinner animation="grow" variant="success" />
|
|
<Spinner animation="grow" variant="danger" />
|
|
<Spinner animation="grow" variant="warning" />
|
|
<Spinner animation="grow" variant="info" />
|
|
</td>
|
|
</tr>
|
|
):(
|
|
classes.length > 0 ?(
|
|
classes.map((data, index) => (
|
|
<tr key={data.ID_CLASS}>
|
|
<td>{index + 1}</td>
|
|
<td>{data.NAME_CLASS}</td>
|
|
<td>{data.TOTAL_STUDENT}</td>
|
|
<td className='text-center action-col d-flex justify-content-center'>
|
|
<NavLink className='btn btn-sm btn-view' to={`class-detail/${data.ID_CLASS}`}><i className="bi bi-eye"></i></NavLink>
|
|
<Button size='sm' className='btn-edit' onClick={() => handleShow(data)}>
|
|
<i className="bi bi-pencil-square"></i>
|
|
</Button>
|
|
<Button size='sm' className='btn-delete' onClick={() => deleteClass(data.ID_CLASS)}>
|
|
<i className="bi bi-trash3"></i>
|
|
</Button>
|
|
</td>
|
|
</tr>
|
|
))
|
|
):(
|
|
<tr>
|
|
<td colSpan={5} style={{height:'20vh'}}>
|
|
<h3>Empty Data</h3>
|
|
</td>
|
|
</tr>
|
|
)
|
|
)}
|
|
</tbody>
|
|
</Table>
|
|
<div className="mt-2 w-100 d-flex justify-content-between align-items-center">
|
|
<div className='d-flex align-items-center'>
|
|
<small className="me-2">Item per page</small>
|
|
<Form.Select
|
|
size='sm'
|
|
className='py-0 px-1 me-2'
|
|
aria-label="Default select example"
|
|
defaultValue='7'
|
|
onChange={handleLimitsChange}
|
|
style={{ width: '50px' }}
|
|
>
|
|
<option value="7">7</option>
|
|
<option value="10">10</option>
|
|
<option value="20">20</option>
|
|
</Form.Select>
|
|
<small>of {totalData}</small>
|
|
</div>
|
|
<TablePaginate
|
|
totalPages={totalPages}
|
|
currentPage={page}
|
|
onPageChange={handlePageChange}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</Tab.Pane>
|
|
<Tab.Pane eventKey="create">
|
|
<div className="cards">
|
|
<div className="cards-title">
|
|
<h4>Add Class Data</h4>
|
|
</div>
|
|
<div className="cards-body">
|
|
<Form onSubmit={(e) => { e.preventDefault(); createClass(); }}>
|
|
<Row className="mb-2">
|
|
<Form.Group as={Col} controlId="formGridClass" className='col-12 col-sm-6'>
|
|
<Form.Label>Class Name<sup className='text-red fw-bold'>*</sup></Form.Label>
|
|
<InputGroup className="mb-2 input-group-icon">
|
|
<InputGroup.Text id="basic-addon1"><i className="bi bi-easel2"></i></InputGroup.Text>
|
|
<Form.Control
|
|
name="className"
|
|
value={formData.className || ''}
|
|
onChange={handleFormChange}
|
|
placeholder="Enter Class Name"
|
|
/>
|
|
</InputGroup>
|
|
</Form.Group>
|
|
<Form.Group as={Col} controlId="formGridCapacity" className='col-12 col-sm-6'>
|
|
<Form.Label>Class Capacity<sup className='text-red fw-bold'>*</sup></Form.Label>
|
|
<InputGroup className="mb-2 input-group-icon">
|
|
<InputGroup.Text id="basic-addon1"><i className="bi bi-person"></i></InputGroup.Text>
|
|
<Form.Control type='number'
|
|
name="capacity"
|
|
value={formData.capacity || ''}
|
|
onChange={handleFormChange}
|
|
placeholder="Enter Class Capacity"
|
|
/>
|
|
</InputGroup>
|
|
</Form.Group>
|
|
</Row>
|
|
<div className="d-flex justify-content-end">
|
|
<Button variant="outline-blue" type="reset" className='ms-auto py-2 rounded-35' onClick={resetForm}>
|
|
reset
|
|
</Button>
|
|
<Button variant="blue" type="submit" className='ms-2 py-2 px-5 rounded-35'>
|
|
Add
|
|
</Button>
|
|
</div>
|
|
</Form>
|
|
</div>
|
|
</div>
|
|
</Tab.Pane>
|
|
</Tab.Content>
|
|
</Col>
|
|
</Row>
|
|
</Tab.Container>
|
|
|
|
<Modal show={show} onHide={handleClose} className='modal-admin' size='lg' centered>
|
|
<Modal.Header closeButton>
|
|
<Modal.Title>Update Class Data</Modal.Title>
|
|
</Modal.Header>
|
|
<Modal.Body>
|
|
<Form onSubmit={(e) => { e.preventDefault(); editClass(); }}>
|
|
<Form.Group as={Col} controlId="updateGridName" className='mb-3'>
|
|
<Form.Label>Class Name<sup className='text-red fw-bold'>*</sup></Form.Label>
|
|
<InputGroup className="mb-2 input-group-icon">
|
|
<InputGroup.Text id="basic-addon1"><i className="bi bi-easel2"></i></InputGroup.Text>
|
|
<Form.Control
|
|
name="className"
|
|
value={formData.className || ''}
|
|
onChange={handleFormChange}
|
|
placeholder="Enter Class Name"
|
|
/>
|
|
</InputGroup>
|
|
</Form.Group>
|
|
<Form.Group as={Col} controlId="updateGridCapacity" className='mb-3'>
|
|
<Form.Label>Class Capacity<sup className='text-red fw-bold'>*</sup></Form.Label>
|
|
<InputGroup className="mb-2 input-group-icon">
|
|
<InputGroup.Text id="basic-addon1"><i className="bi bi-person"></i></InputGroup.Text>
|
|
<Form.Control type='number'
|
|
name="capacity"
|
|
value={formData.capacity || ''}
|
|
onChange={handleFormChange}
|
|
placeholder="Enter Class Capacity"
|
|
/>
|
|
</InputGroup>
|
|
</Form.Group>
|
|
<div className="d-flex justify-content-end">
|
|
<Button variant="blue" type="submit" className='py-2 px-5 w-100 rounded-35'>
|
|
Update
|
|
</Button>
|
|
</div>
|
|
</Form>
|
|
</Modal.Body>
|
|
</Modal>
|
|
|
|
<Modal show={showAssign} onHide={handleClose} className='modal-admin' size='lg'>
|
|
<Modal.Header closeButton>
|
|
<Modal.Title>Assign Student to Class</Modal.Title>
|
|
</Modal.Header>
|
|
<Modal.Body>
|
|
<Form onSubmit={(e) => { e.preventDefault(); assignStudentToClass(); }}>
|
|
<Form.Group as={Col} controlId="formGridEmail" className='mb-3'>
|
|
<Form.Label>Class<sup className='text-red fw-bold'>*</sup></Form.Label>
|
|
<InputGroup className="mb-2 input-group-icon">
|
|
<InputGroup.Text id="basic-addon1"><i className="bi bi-person"></i></InputGroup.Text>
|
|
<Form.Select aria-label="teacher select" required defaultValue="" onChange={assignClassChange}>
|
|
<option value="" disabled hidden>Select Class</option>
|
|
{
|
|
classes.map((data, index) => (
|
|
<option key={data.ID_CLASS} value={data.NAME_CLASS}>{data.NAME_CLASS}</option>
|
|
))
|
|
}
|
|
</Form.Select>
|
|
</InputGroup>
|
|
</Form.Group>
|
|
<Form.Group as={Col} controlId="formGridPassword" className='mb-3'>
|
|
<Form.Label>Student<sup className='text-red fw-bold'>*</sup></Form.Label>
|
|
<InputGroup className="mb-2 input-group-icon">
|
|
<InputGroup.Text id="basic-addon1"><i className="bi bi-person-vcard"></i></InputGroup.Text>
|
|
<Select
|
|
className='group-react-select'
|
|
classNamePrefix='react-select-group'
|
|
required={true}
|
|
isMulti
|
|
options={freeStudent}
|
|
onChange={assignStudentChange}
|
|
placeholder="Select Students"
|
|
backspaceRemovesValue={true}
|
|
closeMenuOnSelect={false}
|
|
menuPosition="fixed"
|
|
/>
|
|
</InputGroup>
|
|
</Form.Group>
|
|
<div className="d-flex justify-content-end">
|
|
<Button variant="blue" type="submit" className='py-2 px-5 w-100 rounded-35'>
|
|
Add
|
|
</Button>
|
|
</div>
|
|
</Form>
|
|
</Modal.Body>
|
|
</Modal>
|
|
|
|
<ModalOperation
|
|
show={showLoader}
|
|
handleClose={handleCloseLoader}
|
|
title={loaderState.title}
|
|
description={loaderState.description}
|
|
loading={loaderState.loading}
|
|
successMessage={loaderState.successMessage}
|
|
confirmAction={loaderState.confirmAction}
|
|
handleConfirm={loaderState.handleConfirm}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ManageClasses;
|