@ -1,22 +1,26 @@
import { useEffect , useState } from "react" ;
import Header from "../../../_components/Header" ;
import { renderIconHome } from "../../../_components/renderIcon" ;
import { renderIconButton , renderIcon Home , renderIconSearchInput } from "../../../_components/renderIcon" ;
import RateStar from "../../../_components/RateStar" ;
import { defaultMonthYearSemester , getListMonthBySemester , LIST _SCHOOL _YEAR , LIST _SEMESTER , PRIMARY _COLOR } from "../../../_constants/common" ;
import { configConstants , PATH } from "../../../_constants" ;
import RootSelect from "../../../_components/RootSelect" ;
import PrimaryButton from "../../../_components/Button/PrimaryButton" ;
import { useSelector } from "react-redux" ;
import { useDispatch , use Selector } from "react-redux" ;
import './detailRoomEducation.style.scss'
import BoxDoughnutChart from "../../../_components/boxChart/BoxDoughnutChar" ;
import BoxDoughnutBarChart from "../../../_components/boxChart/BoxDoughnutBarChart" ;
import { apiCaller , history } from "../../../_helpers" ;
import { replacePathParams } from "../../../_helpers/utils" ;
import { exportExcel , replacePathParams } from "../../../_helpers/utils" ;
import $ from "jquery" ;
import { useParams } from "react-router-dom" ;
import { useLocation , useParams } from "react-router-dom" ;
import InputText from "../../../_components/Auth/InputText" ;
import { alertActions } from "../../../_actions" ;
export default function DetailRoomEducation ( ) {
const { idRoom } = useParams ( )
const location = useLocation ( ) ;
const isBack = location . state ? . isBack ;
const grade = useSelector ( ( state ) => state . grade ) ;
const authentication = useSelector ( ( state ) => state . authentication ) ;
const [ dateStudentChart , setDateStudentChart ] = useState ( new Date ( ) )
@ -34,6 +38,16 @@ export default function DetailRoomEducation() {
const [ isLoadingStatisticCircle , setIsLoadingStatisticCircle ] = useState ( false ) ;
const [ isLoadingStudentChart , setIsLoadingStudentChart ] = useState ( false ) ;
const [ isLoadingTeacherChart , setIsLoadingTeacherChart ] = useState ( false ) ;
const [ isFilterChanged , setIsFilterChanged ] = useState ( false ) ;
const [ isLoadMoreOnline , setLoadMoreOnline ] = useState ( true ) ;
const [ limitOnline ] = useState ( 10 ) ;
const [ offsetOnline , setOffsetOnline ] = useState ( 0 ) ;
const [ isEndOnlineClasses , setIsEndOnlineClasses ] = useState ( false ) ;
const [ isLoading , setIsLoading ] = useState ( false ) ;
const [ searchText , setSearchText ] = useState ( '' ) ;
const dispatch = useDispatch ( ) ;
const isSGD = authentication ? . user ? . organization _name ? . toLowerCase ( ) . includes ( 'sở' ) ;
const getListOrganization = async ( ) => {
try {
@ -185,23 +199,41 @@ export default function DetailRoomEducation() {
}
const goToDetailSchool = ( item ) => {
history . push ( replacePathParams ( PATH . home . detailSchool , { schoolId : item ? . organization _id } ) +
"?school_name=" +
encodeURIComponent ( item ? . organization _name ) ) ;
const schoolId = item ? . organization _id ;
const schoolName = encodeURIComponent ( item ? . organization _name ) ;
const detailPath = replacePathParams ( PATH . home . detailSchool , { schoolId } ) ;
history . push ( {
pathname : detailPath ,
search : ` ?school_name= ${ schoolName } ` ,
state : { isBack : true }
} ) ;
}
useEffect ( ( ) => {
getDataStatisticCircle ( )
getListOrganization ( )
} , [ ] )
const fetchData = async ( ) => {
await getDataStatisticCircle ( ) ;
await getListOrganization ( ) ;
} ;
fetchData ( ) ;
} , [ ] ) ;
useEffect ( ( ) => {
getDataStudentChart ( )
} , [ dateStudentChart ] )
const fetchStudentData = async ( ) => {
await getDataStudentChart ( ) ;
} ;
fetchStudentData ( ) ;
} , [ dateStudentChart ] ) ;
useEffect ( ( ) => {
getDataTeacherChart ( )
} , [ dateTeacherChart ] )
const fetchTeacherData = async ( ) => {
await getDataTeacherChart ( ) ;
} ;
fetchTeacherData ( ) ;
} , [ dateTeacherChart ] ) ;
useEffect ( ( ) => {
if ( isLoadingListOrganization || isLoadingStatisticCircle || isLoadingStudentChart || isLoadingTeacherChart ) {
@ -211,49 +243,165 @@ export default function DetailRoomEducation() {
}
} , [ isLoadingListOrganization , isLoadingStatisticCircle , isLoadingStudentChart , isLoadingTeacherChart ] )
const renderIconButton = ( ) => {
return (
< svg xmlns = "http://www.w3.org/2000/svg" width = "24" height = "24" viewBox = "0 0 24 24" > < g fill = "none" stroke = "#fff" stroke - linecap = "round" stroke - linejoin = "round" stroke - width = "2" > < path stroke - dasharray = "20" stroke - dashoffset = "20" d = "M3 12h17.5" > < animate fill = "freeze" attributeName = "stroke-dashoffset" dur = "0.2s" values = "20;0" / > < /path><path stroke-dasharray="12" stroke-dashoffset="12" d="M21 12l-7 7M21 12l-7 -7"><animate fill="freeze" attributeName="stroke-dashoffset" begin="0.2s" dur="0.2s" values="12;0"/ > < /path></g > < / s v g >
)
}
const handleScroll = ( e ) => {
if (
e . target . scrollHeight - e . target . scrollTop < e . target . clientHeight + 5 &&
isLoadMoreOnline &&
! isLoading
) {
if ( listOrganization . length < limitOnline ) return
onLoadMoreClasses ( ) ;
}
} ;
// Load More Classes for Teacher
const onLoadMoreClasses = async ( ) => {
let offsetOnlineMore = offsetOnline + limitOnline ;
let listNext = [ ] ;
setIsLoading ( true ) ;
try {
if ( ! isEndOnlineClasses ) {
const endPoint = ` /report/api_report/getListOrganizationFromDistrictOrganization?organization_id= ${
idRoom
} $ {
! ! schoolYear ? . value ? ` &year= ${ schoolYear ? . value } ` : ""
} $ {
! ! semester ? . value ? ` &semester= ${ semester ? . value } ` : ""
} $ {
! ! month ? . value ? ` &month= ${ month ? . value } ` : ""
} & limit = $ { limitOnline } & offset = $ { offsetOnlineMore } ` ;
const res = await apiCaller (
endPoint ,
"GET" ,
{ } ,
null ,
true ,
configConstants . API _URL _SETEST ,
false
)
// const endPoint = `/report/api_report/getOrganizationAndCriteria?limit=${limitOnline}&offset=${offsetOnlineMore}${
// queryParams.length ? `&${queryParams.join("&")}` : ""
// }`;
// const res = await apiCaller(endPoint, "GET");
if ( ! res . data ) {
setIsEndOnlineClasses ( true ) ;
} else {
listNext = res ? . data ;
setOffsetOnline ( offsetOnline + limitOnline ) ;
if ( res ? . data ? . length < limitOnline ) {
setLoadMoreOnline ( false ) ;
if ( res ? . data ? . length == 0 ) setLoadMoreOnline ( false ) ;
setIsEndOnlineClasses ( true ) ;
}
}
} else {
setIsEndOnlineClasses ( true ) ;
}
let listPrev = listOrganization ;
setListOrganization ( listPrev ? . concat ( listNext ) ) ;
} catch ( e ) {
} finally {
setIsLoading ( false ) ;
}
} ;
const handleExport = ( ) => {
const listHeader = [
'Stt' ,
'Tên trường' ,
'Tiêu chí giao bài' ,
'Tiêu chí tỷ lệ học sinh làm bài' ,
'Mức độ hoàn thành tiêu chí' ,
'Huyện' ,
'Tỉnh'
] ;
const listData = listOrganization . map ( ( item , index ) => [
index + 1 ,
item . organization _name || '' ,
item . criteria _level || 0 ,
item . student _done _per _level || 0 ,
item . assign _number _level || 0 ,
item . district || '' ,
item . province || '' ,
] ) ;
exportExcel ( listHeader , listData , ` Danh sách trường.xlsx ` ) ;
} ;
const getDataTeacher = async ( ) => {
try {
setIsLoading ( true ) ;
const endPoint = ` /api_teacher/get_teacher_info?search= ${ searchText } ` ;
const res = await apiCaller ( endPoint , "GET" ) ;
setIsLoading ( false ) ;
if ( res ? . status ) {
const teacherId = res ? . data ? . [ 0 ] ? . teacher _id ;
const teacherName = encodeURIComponent ( res ? . data ? . [ 0 ] ? . teacher _name ) ;
const detailPath = replacePathParams ( PATH . home . detailTeacher , { teacherId } ) ;
history . push ( {
pathname : detailPath ,
search : ` ?teacher_name= ${ teacherName } ` ,
state : { isBack : true }
} ) ;
}
} catch ( err ) {
setIsLoading ( false ) ;
dispatch (
alertActions . error ( {
message : err ? . toString ( ) ,
} ) ,
) ;
}
} ;
const handleSubmit = ( ) => {
getDataTeacher ( )
}
return (
< div className = "flex-1" >
< Header
icon = { renderIconHome ( { color : "#4D4D4D" } ) }
title = { "Phòng giáo dục huyện Giao Thủy" }
title = { "Phòng giáo dục " + ( isSGD ? ` ${ authentication . user . province } ` : ` ${ authentication . user . district } ` ) }
manager = { true }
isBack = { isBack }
/ >
< div className = "container-page-header container-page-sidebar" >
< div className = "detail-room-education-container bg-sub-main-green-img" >
< div className = "detail-room-education-left-side" >
< div className = "detail-room-education-statistic-container" >
< div className = "d-flex flex-1 gap-16" style = { { flexDirection : 'column' } } >
< div className = "flex flex-m gap-16" style = { { height : '23%' } } >
{ data ?
( < >
< div className = "flex flex-m gap-16" style = { { height : '23%' } } >
< BoxDoughnutChart data = { [ data ? . school _join , data ? . total _school ] } title = { 'Số trường đã tham gia' } / >
< BoxDoughnutChart data = { [ data ? . class _join , data ? . total _class ] } title = { 'Số lớp đã tham gia' } / >
< / d i v >
< div className = "flex flex-m flex-1 gap-16" >
< BoxDoughnutBarChart
dateBarChat = { dateTeacherChart }
onSetDateBarChart = { setDateTeacherChart }
dataBarChart = { dataTeacherChart ? . map ( item => Number ( item ? . total _teacher _assignment ) ) }
labelsBarChart = { dataTeacherChart ? . map ( item => item ? . label ) }
dataDoughnut = { [ data ? . teacher _join , data ? . total _teacher ] }
titleDoughnut = { 'Giáo viên' }
subtitleDoughnut = { 'Số giáo viên đã tham gia' }
subTitleLine = { "Số giáo viên giao bài trong tuần" }
/ >
< BoxDoughnutBarChart
dateBarChat = { dateStudentChart }
onSetDateBarChart = { setDateStudentChart }
dataBarChart = { dataStudentChart ? . map ( item => Number ( item ? . total _student _learn ) ) }
labelsBarChart = { dataStudentChart ? . map ( item => item ? . label ) }
dataDoughnut = { [ data ? . student _join , data ? . total _student ] }
titleDoughnut = { 'Học sinh' }
subtitleDoughnut = { 'Số học sinh đã tham gia' }
subTitleLine = { "Số học sinh làm bài trong tuần" }
/ >
< / d i v >
< / d i v >
< div className = "flex flex-m flex-1 gap-16" >
< BoxDoughnutBarChart
dateBarChat = { dateTeacherChart }
onSetDateBarChart = { setDateTeacherChart }
dataBarChart = { dataTeacherChart ? . map ( item => Number ( item ? . total _teacher _assignment ) ) }
labelsBarChart = { dataTeacherChart ? . map ( item => item ? . label ) }
dataDoughnut = { [ data ? . teacher _join , data ? . total _teacher ] }
titleDoughnut = { 'Giáo viên' }
subtitleDoughnut = { 'Số giáo viên đã tham gia' }
subTitleLine = { "Số giáo viên giao bài trong tuần" }
/ >
< BoxDoughnutBarChart
dateBarChat = { dateStudentChart }
onSetDateBarChart = { setDateStudentChart }
dataBarChart = { dataStudentChart ? . map ( item => Number ( item ? . total _student _learn ) ) }
labelsBarChart = { dataStudentChart ? . map ( item => item ? . label ) }
dataDoughnut = { [ data ? . student _join , data ? . total _student ] }
titleDoughnut = { 'Học sinh' }
subtitleDoughnut = { 'Số học sinh đã tham gia' }
subTitleLine = { "Số học sinh làm bài trong tuần" }
/ >
< / d i v >
< / > )
:
"Không có dữ liệu để hiển thị"
}
< / d i v >
< div className = "d-flex justify-content-center" style = { { marginTop : '3rem' } } >
< PrimaryButton className = "d-flex" style = { { textDecoration : 'underline' } } onClick = { goToOutstandingTeacher } >
@ -265,31 +413,71 @@ export default function DetailRoomEducation() {
< / d i v >
< div className = "detail-room-education-right-side" >
< div className = "detail-room-education-list-container" >
< span style = { { fontSize : '2rem' , fontWeight : 700 , padding : '0 3.2rem' } } > Danh sách trường < / s p a n >
< div className = "flex gap-16 align-item-center" style = { { padding : '1rem 3.2rem' } } >
< div className = "detail-room-education-header" >
< span style = { { fontSize : '2rem' , fontWeight : 700 , padding : '0 3.2rem' } } > Danh sách trường < / s p a n >
< div className = "d-flex detail-room-education-list-header" >
< InputText
className = "criteria-manage-search-input criteria-manage-item"
value = { searchText }
setValue = { setSearchText }
type = "text"
name = "searchText"
placeholder = { "Nhập email hoặc số điện thoại giáo viên" }
renderLabelIcon = { renderIconSearchInput }
onKeyUp = { ( e ) => {
if ( e . which == 13 && ! isFilterSchool ) {
handleSubmit ( ) ;
}
} }
/ >
< PrimaryButton
isDisabled = { searchText . length === 0 }
onClick = { handleSubmit }
>
{ "Tìm kiếm" }
< / P r i m a r y B u t t o n >
< PrimaryButton isDisabled = { listOrganization . length === 0 } onClick = { handleExport } >
Xuất excel
< / P r i m a r y B u t t o n >
< / d i v >
< / d i v >
< div className = "flex gap-16 align-item-center" style = { { padding : '1rem' } } >
< RootSelect
data = { LIST _SCHOOL _YEAR }
value = { schoolYear }
setValue = { setSchoolYear }
style = { { flex : 1 } }
setValue = { ( value ) => {
setSchoolYear ( value ) ;
setIsFilterChanged ( true ) ;
} }
style = { { flex : 1 , minWidth : '200px' , padding : '0 10px' } }
/ >
< RootSelect
data = { LIST _SEMESTER }
value = { semester }
setValue = { changeSemester }
style = { { flex : 0.5 } }
setValue = { ( value ) => {
changeSemester ( value ) ;
setIsFilterChanged ( true ) ;
} }
style = { { flex : 0.5 , minWidth : '151px' , padding : '0 10px' } }
/ >
< RootSelect
data = { getListMonthBySemester ( semester . value ) }
value = { month }
setValue = { setMonth }
style = { { flex : 0.5 } }
setValue = { ( value ) => {
setMonth ( value ) ;
setIsFilterChanged ( true ) ;
} }
style = { { flex : 0.5 , minWidth : '150px' , padding : '0 10px' } }
/ >
< PrimaryButton onClick = { handleFilter } >
< PrimaryButton isDisabled = { ! isFilterChanged } onClick = { ( ) => {
handleFilter ( ) ;
setIsFilterChanged ( false ) ;
} } >
Áp dụng
< / P r i m a r y B u t t o n >
< / d i v >
< div className = "detail-room-education-list detail-room-education-right-p-h scrollbar-custom" >
< div onScroll = { handleScroll } className = "detail-room-education-list detail-room-education-right-p-h scrollbar-custom" >
{ ! isLoadingListOrganization && ! listOrganization ? . length && (
< p style = { { fontSize : '1.8rem' , fontWeight : 700 } } >
Không có trường nào
@ -300,7 +488,7 @@ export default function DetailRoomEducation() {
< div className = "detail-room-education-item" key = { index } onClick = { ( ) => goToDetailSchool ( item ) } >
< div className = "detail-room-education-item-content" >
< div className = "detail-room-education-avatar" >
< img src = { configConstants . BASE _URL + item ? . avatar } / >
< img src = { item ? . avatar ? configConstants . BASE _URL + item ? . avatar : "/assets/imgs/avatar_school.png" } / >
< / d i v >
< div className = "detail-room-education-detail" >
< div className = "detail-room-education-info" >