2024-10-31 02:32:14 +00:00
|
|
|
import React from 'react';
|
|
|
|
|
import { Table, Row, Col, Card, Button, Spinner } from 'react-bootstrap';
|
2024-12-16 07:24:16 +00:00
|
|
|
import { NavLink, Link } from 'react-router-dom';
|
2024-10-31 02:32:14 +00:00
|
|
|
import useDashboard from '../hooks/useDashboard';
|
|
|
|
|
|
|
|
|
|
function validName(text) {
|
|
|
|
|
const words = text.trim().split(" ");
|
|
|
|
|
return words.slice(0, 2).join(" ");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const AdminDashboard = () => {
|
|
|
|
|
const { username } = JSON.parse(localStorage.getItem('userData'));
|
|
|
|
|
const {
|
|
|
|
|
error,
|
|
|
|
|
totalStudent,
|
|
|
|
|
totalTeacher,
|
|
|
|
|
reports,
|
|
|
|
|
activity,
|
|
|
|
|
loadingActivity,
|
|
|
|
|
loadingReports,
|
|
|
|
|
formatLocalDate
|
|
|
|
|
} = useDashboard();
|
|
|
|
|
return (
|
|
|
|
|
<div className='admin-dashboard'>
|
|
|
|
|
<h2 className='page-title'>Hi, {validName(username)}!</h2>
|
|
|
|
|
<p className='page-desc'>Together, we can make every learning journey smarter and more adaptive.</p>
|
|
|
|
|
<Row className='mb-45'>
|
|
|
|
|
<Col md={4} xxl={2}>
|
|
|
|
|
<div className="mini-cards p-4 mb-3">
|
|
|
|
|
<h4 className='m-0'>All Student</h4>
|
|
|
|
|
<hr />
|
|
|
|
|
<h1 className='m-0 fw-bold text-blue'>{totalStudent}</h1>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="mini-cards p-4">
|
|
|
|
|
<h4 className='m-0'>All Teacher</h4>
|
|
|
|
|
<hr />
|
|
|
|
|
<h1 className='m-0 fw-bold text-blue'>{totalTeacher}</h1>
|
|
|
|
|
</div>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col md={8} xxl={10}>
|
|
|
|
|
<div className="cards">
|
|
|
|
|
<div className="cards-title">
|
|
|
|
|
<h4>Recent Student Activities</h4>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="cards-body">
|
|
|
|
|
<Table hover>
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
2024-12-16 07:24:16 +00:00
|
|
|
<th>Full Name</th>
|
|
|
|
|
<th className='text-center'>Class</th>
|
2024-10-31 02:32:14 +00:00
|
|
|
<th>Topic</th>
|
2024-12-16 07:24:16 +00:00
|
|
|
<th>Level</th>
|
|
|
|
|
<th className='text-center'>Score</th>
|
|
|
|
|
<th className='text-center'>Review</th>
|
2024-10-31 02:32:14 +00:00
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
{loadingActivity?(
|
|
|
|
|
<tr>
|
2024-12-16 07:24:16 +00:00
|
|
|
<td colSpan={6} style={{height:"20vh"}}>
|
2024-10-31 02:32:14 +00:00
|
|
|
<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>
|
|
|
|
|
):(
|
|
|
|
|
activity.length > 0?(
|
|
|
|
|
activity.map((data, index) => (
|
2024-12-16 07:24:16 +00:00
|
|
|
<tr key={index}>
|
|
|
|
|
<td>{data.NAME_USERS}</td>
|
|
|
|
|
<td className='text-center'>{data.NAME_CLASS ? data.NAME_CLASS : '-'}</td>
|
|
|
|
|
<td>{data.NAME_TOPIC}</td>
|
|
|
|
|
<td>{data.NAME_LEVEL}</td>
|
|
|
|
|
<td className='text-center'>{data.SCORE}</td>
|
|
|
|
|
<td className='text-center action-col'>
|
|
|
|
|
<Link className='btn btn-sm btn-view' to={`s/${data.ID_STUDENT_LEARNING}`}><i className="bi bi-eye"></i></Link>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
2024-10-31 02:32:14 +00:00
|
|
|
))
|
|
|
|
|
):(
|
|
|
|
|
<tr>
|
2024-12-16 07:24:16 +00:00
|
|
|
<td colSpan={6} style={{height:'20vh'}}>
|
2024-10-31 02:32:14 +00:00
|
|
|
<h3>Empty Data</h3>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
)
|
|
|
|
|
)}
|
|
|
|
|
</tbody>
|
|
|
|
|
</Table>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
|
|
|
|
<Row className='mb-45'>
|
|
|
|
|
<Col sm={12}>
|
|
|
|
|
<div className="cards">
|
|
|
|
|
<div className="cards-title d-flex justify-content-between align-items-center">
|
|
|
|
|
<h4>Issue Reports</h4>
|
|
|
|
|
<NavLink to="/admin/report" className="text-blue">See more</NavLink>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="cards-body">
|
|
|
|
|
<Table hover>
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th>No</th>
|
|
|
|
|
<th>Email Address</th>
|
|
|
|
|
<th>Full Name</th>
|
|
|
|
|
<th>Report</th>
|
|
|
|
|
<th>Time</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
{loadingReports?(
|
|
|
|
|
<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>
|
|
|
|
|
):(
|
|
|
|
|
reports.length > 0?(
|
|
|
|
|
reports.map((data, index) => (
|
|
|
|
|
<tr key={index}>
|
|
|
|
|
<td>{index + 1}</td>
|
|
|
|
|
<td>{data.USER_EMAIL}</td>
|
|
|
|
|
<td>{data.USER_EMAIL}</td>
|
|
|
|
|
<td>{data.REPORTS}</td>
|
|
|
|
|
<td>{formatLocalDate(data.TIME_REPORT)}</td>
|
|
|
|
|
</tr>
|
|
|
|
|
))
|
|
|
|
|
):(
|
|
|
|
|
<tr>
|
|
|
|
|
<td colSpan={5} style={{height:'20vh'}}>
|
|
|
|
|
<h3>Empty Data</h3>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
)
|
|
|
|
|
)}
|
|
|
|
|
</tbody>
|
|
|
|
|
</Table>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default AdminDashboard;
|