Compare commits

...

9 Commits

  1. 8
      src/_components/boxChart/BoxDoughnutBarChart.js
  2. 4
      src/_components/boxChart/BoxDoughnutChar.js
  3. 8
      src/_components/boxChart/boxChart.scss
  4. 30
      src/_components/chart/RDoughnutChart.js
  5. 16
      src/_components/renderIcon/index.js
  6. 5
      src/_screens/criteria/criteria-setting/index.js
  7. 28
      src/_screens/home/admin/index.js
  8. 1
      src/_screens/home/detail-grade/index.js
  9. 22
      src/_screens/home/detail-room-education/detailRoomEducation.style.scss
  10. 105
      src/_screens/home/detail-room-education/index.js
  11. 26
      src/_screens/home/education-department/educationDepartmentHome.style.scss
  12. 89
      src/_screens/home/education-department/index.js
  13. 23
      src/_screens/home/headmaster/index.js
  14. 22
      src/_screens/home/outstanding-teacher/index.js
  15. 1
      src/_screens/home/outstanding-teacher/outstandingTeacher.style.scss
  16. 5
      src/_screens/home/teacher/index.js

@ -58,8 +58,10 @@ export default function BoxDoughnutBarChart({
{titleLine && <p className='box-chart-title'>{titleLine}</p>} {titleLine && <p className='box-chart-title'>{titleLine}</p>}
{subTitleLine && <p className='box-chart-subtitle'>{subTitleLine}</p>} {subTitleLine && <p className='box-chart-subtitle'>{subTitleLine}</p>}
{dataBarChart.length > 0 ? ( {dataBarChart.length > 0 ? (
<div className='flex-1' style={{padding: '1.6rem 0'}}> <div className='chart-container'>
<VerticalBarChart data={dataBarChart} labels={labelsBarChart}/> <div className='flex-1' style={{ padding: '1.6rem 0', height: '100%', width: '360px' }}>
<VerticalBarChart data={dataBarChart} labels={labelsBarChart} />
</div>
</div> </div>
) : ( ) : (
<div className="d-flex justify-content-center align-items-center flex-1"> <div className="d-flex justify-content-center align-items-center flex-1">
@ -101,7 +103,7 @@ export default function BoxDoughnutBarChart({
<div className="box-chart-container"> <div className="box-chart-container">
{renderDoughnutSection()} {renderDoughnutSection()}
{renderBarSection()} {renderBarSection()}
<div className='d-flex justify-content-center align-items-center'> <div className='d-flex justify-content-center align-items-center' style={{marginTop:'1.2rem'}}>
<Btn icon={renderIconButtonLeft()} isDisabled={false} onClick={handleClickPrev} /> <Btn icon={renderIconButtonLeft()} isDisabled={false} onClick={handleClickPrev} />
<div className='d-flex justify-content-center align-item-center' style={{width: 140, alignSelf: 'center'}}> <div className='d-flex justify-content-center align-item-center' style={{width: 140, alignSelf: 'center'}}>
<InputDate <InputDate

@ -5,7 +5,7 @@ import './boxChart.scss'
export default function BoxDoughnutChart({data = [], title, propsContainer}) { export default function BoxDoughnutChart({data = [], title, propsContainer}) {
const [current, target] = data const [current, target] = data
const chartData = (current / target === 1 || current > target) ? [current] : [current, target - current]; // const chartData = (current / target === 1 || current > target) ? [current] : [current, target - current];
const renderStats = () => { const renderStats = () => {
return ( return (
@ -21,7 +21,7 @@ export default function BoxDoughnutChart({data = [], title, propsContainer}) {
<p className='box-chart-subtitle'>{title}</p> <p className='box-chart-subtitle'>{title}</p>
<div className='d-flex flex-1'> <div className='d-flex flex-1'>
<div className='doughnut-chart-content flex-1'> <div className='doughnut-chart-content flex-1'>
<RDoughnutChart data={chartData} /> <RDoughnutChart data={data} />
</div> </div>
<div className='origin-vertical justify-content-center align-item-center flex-1'> <div className='origin-vertical justify-content-center align-item-center flex-1'>
{renderStats()} {renderStats()}

@ -48,4 +48,12 @@
background: #c1c1c1 !important; background: #c1c1c1 !important;
pointer-events: none; pointer-events: none;
} }
.chart-container {
// max-width: 360px;
overflow-x: scroll;
height: 100%;
@media (max-width: 1750px) {
max-width: 300px;
}
}
} }

@ -10,36 +10,44 @@ export default function RDoughnutChart({data = [], ...other}) {
return null return null
} }
// data = data.map((item, index) => { const total = data[1] === 0 ? 1 : data[0] + data[1];
// if (index === 1 && item === 0) { const percentageData = [
// return 1 (data[0] / total) * 100,
// } (data[1] / total) * 100,
// return item ];
// })
// console.log('data',data); const adjustedData = (percentageData[0] === 0 && percentageData[1] === 0) || percentageData[1] === percentageData[0] ? [0, 1] : percentageData;
return <Chart return <Chart
type='doughnut' type='doughnut'
data={{ data={{
labels: [], labels: ['Số tham gia',"Tổng số"],
datasets: [ datasets: [
{ {
label: '', label: '',
data, data: adjustedData,
backgroundColor: [ backgroundColor: [
PRIMARY_COLOR, '#01AEF0' PRIMARY_COLOR, '#01AEF0'
], ],
borderWidth: 0 borderWidth: 0
}, },
], ],
hoverOffset: 4
}} }}
options={{ options={{
responsive: true, responsive: true,
maintainAspectRatio: false, maintainAspectRatio: false,
plugins: { plugins: {
tooltip: { tooltip: {
enabled: false callbacks: {
} label: function (tooltipItem) {
const label = tooltipItem.label || '';
const value = data[tooltipItem.dataIndex];
return `${label}: ${value}`;
},
},
},
legend: false,
} }
}} }}
{...other} {...other}

@ -174,3 +174,19 @@ export const renderIconDate = () => (
/> />
</svg> </svg>
) )
export const renderIconBook = () => {
return (
<svg
width="29"
height="29"
viewBox="0 0 29 29"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M15.2359 2.71875L3.12973 6.05873H3.11342C2.91223 6.05873 0.90625 6.11492 0.90625 8.35789C0.90625 9.33256 1.33853 10.0589 1.33853 10.0589L10.5614 25.4842C11.4432 26.8889 13.316 26.0094 13.316 26.0094L27.4585 19.1196L26.9292 18.5827C26.8046 17.9379 26.7321 16.7439 27.6075 15.8548C27.627 15.8349 27.6307 15.8077 27.6411 15.7828L28.0938 15.6011L15.2359 2.71875ZM15.6115 5.66044L18.0869 8.35517L8.84727 11.7387L6.66502 8.30578L15.6115 5.66044ZM10.2343 23.1719L2.12153 9.60172C2.11791 9.59673 1.8125 9.05389 1.8125 8.35789C1.8125 7.4752 2.24478 7.13944 2.66755 7.02208L11.9444 21.4931C11.2461 21.7953 10.4658 22.4859 10.2343 23.1719ZM26.4679 17.2826C26.4385 17.4911 26.4235 17.6941 26.4267 17.8844L17.1426 22.291L26.4598 18.3371C26.4688 18.4096 26.477 18.4816 26.4883 18.5469L14.587 24.2952L26.5821 18.9751L26.5894 19.0036L13.316 25.3533C13.3096 25.3573 12.7038 25.6795 12.0966 25.6795C11.4967 25.6795 11.1229 25.3714 10.9525 24.7379C10.5143 23.1103 13.0038 22.1877 13.0414 22.1741L26.8087 16.2178C26.7099 16.399 26.6415 16.5839 26.5844 16.7674L17.845 20.8814L26.4679 17.2826Z"
fill="white"
/>
</svg>
);
};

@ -93,7 +93,7 @@ export default function CriteriaSetting() {
const saveCriteriaSetting = async () => { const saveCriteriaSetting = async () => {
try { try {
const dataSave = { const dataSave = {
school_list: schoolList, school_list: schoolList || [authentication?.user?.organization_id],
assign_number_active: criteriaTarget.assign.enable ? 1 : 0, assign_number_active: criteriaTarget.assign.enable ? 1 : 0,
assign_number_target_1: criteriaTarget.assign.target1, assign_number_target_1: criteriaTarget.assign.target1,
assign_number_target_2: criteriaTarget.assign.target2, assign_number_target_2: criteriaTarget.assign.target2,
@ -124,7 +124,7 @@ export default function CriteriaSetting() {
return await apiCaller( return await apiCaller(
"/report/api_report/removeCriteriaFromOrganization", "/report/api_report/removeCriteriaFromOrganization",
"PUT", "PUT",
{ school_list: schoolList } { school_list: schoolList || [authentication?.user?.organization_id] }
); );
} else { } else {
return await apiCaller( return await apiCaller(
@ -244,7 +244,6 @@ export default function CriteriaSetting() {
}, },
}) })
} }
disabled={onlyRead()}
/> />
</div> </div>
<div style={{ width: "100%" }}> <div style={{ width: "100%" }}>

@ -94,13 +94,15 @@ export default function AdminHome() {
const res = await apiCaller(endPoint, "GET"); const res = await apiCaller(endPoint, "GET");
setIsLoading(false); setIsLoading(false);
if (res?.status) { if (res?.status) {
history.push( const teacherId = res?.data?.[0]?.teacher_id;
replacePathParams(PATH.home.detailTeacher, { const teacherName = encodeURIComponent(res?.data?.[0]?.teacher_name);
teacherId: res?.data?.[0]?.teacher_id, const detailPath = replacePathParams(PATH.home.detailTeacher, { teacherId});
}) +
"?teacher_name=" + history.push({
encodeURIComponent(res?.data?.[0]?.teacher_name), pathname: detailPath,
); search: `?teacher_name=${teacherName}`,
state: { isBack: true }
});
} }
} catch (err) { } catch (err) {
setIsLoading(false); setIsLoading(false);
@ -189,9 +191,15 @@ export default function AdminHome() {
const handleClickSchoolItem = (item) => { const handleClickSchoolItem = (item) => {
saveCurrentState() saveCurrentState()
history.push(replacePathParams(PATH.home.detailSchool, {schoolId: item?.organization_id}) + const schoolId = item?.organization_id;
"?school_name=" + const schoolName = encodeURIComponent(item?.organization_name);
encodeURIComponent(item?.organization_name)); const detailPath = replacePathParams(PATH.home.detailSchool, { schoolId});
history.push({
pathname: detailPath,
search: `?school_name=${schoolName}`,
state: { isBack: true }
});
}; };
const handleSubmit = () => { const handleSubmit = () => {

@ -196,6 +196,7 @@ export default function DetailGrade() {
icon={renderIconHome({ color: "#4D4D4D" })} icon={renderIconHome({ color: "#4D4D4D" })}
title={schoolName} title={schoolName}
subtitles={[gradeName]} subtitles={[gradeName]}
isBack={true}
/> />
<div className="container-page-header container-page-sidebar"> <div className="container-page-header container-page-sidebar">
<div className="detail-grade-container bg-main-img"> <div className="detail-grade-container bg-main-img">

@ -29,13 +29,33 @@
.detail-room-education-right-p-h { .detail-room-education-right-p-h {
padding-right: 32px; padding-right: 32px;
} }
.detail-room-education-list-container { .detail-room-education-list-container {
padding: 2rem 0; padding: 2rem 0;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
.detail-room-education-header{
width: 100%;
.detail-room-education-list-header{
justify-content: space-around;
margin: 12px 32px;
gap: 32px;
.criteria-manage-search-input {
height: 46px;
border-radius: 40px;
@include screen_pc_sm {
height: 36px;
}
}
.criteria-manage-item {
min-width: fit-content;
flex: 1;
}
}
}
.detail-room-education-list { .detail-room-education-list {
flex: 1; flex: 1;
gap: 20px; gap: 20px;

@ -1,22 +1,26 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import Header from "../../../_components/Header"; import Header from "../../../_components/Header";
import { renderIconButton, renderIconHome } from "../../../_components/renderIcon"; import { renderIconButton, renderIconHome, renderIconSearchInput } from "../../../_components/renderIcon";
import RateStar from "../../../_components/RateStar"; import RateStar from "../../../_components/RateStar";
import { defaultMonthYearSemester, getListMonthBySemester, LIST_SCHOOL_YEAR, LIST_SEMESTER, PRIMARY_COLOR } from "../../../_constants/common"; import { defaultMonthYearSemester, getListMonthBySemester, LIST_SCHOOL_YEAR, LIST_SEMESTER, PRIMARY_COLOR } from "../../../_constants/common";
import { configConstants, PATH } from "../../../_constants"; import { configConstants, PATH } from "../../../_constants";
import RootSelect from "../../../_components/RootSelect"; import RootSelect from "../../../_components/RootSelect";
import PrimaryButton from "../../../_components/Button/PrimaryButton"; import PrimaryButton from "../../../_components/Button/PrimaryButton";
import { useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import './detailRoomEducation.style.scss' import './detailRoomEducation.style.scss'
import BoxDoughnutChart from "../../../_components/boxChart/BoxDoughnutChar"; import BoxDoughnutChart from "../../../_components/boxChart/BoxDoughnutChar";
import BoxDoughnutBarChart from "../../../_components/boxChart/BoxDoughnutBarChart"; import BoxDoughnutBarChart from "../../../_components/boxChart/BoxDoughnutBarChart";
import { apiCaller, history } from "../../../_helpers"; import { apiCaller, history } from "../../../_helpers";
import { replacePathParams } from "../../../_helpers/utils"; import { exportExcel, replacePathParams } from "../../../_helpers/utils";
import $ from "jquery"; 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() { export default function DetailRoomEducation() {
const {idRoom} = useParams() const {idRoom} = useParams()
const location = useLocation();
const isBack = location.state?.isBack;
const grade = useSelector((state) => state.grade); const grade = useSelector((state) => state.grade);
const authentication = useSelector((state) => state.authentication); const authentication = useSelector((state) => state.authentication);
const [dateStudentChart, setDateStudentChart] = useState(new Date()) const [dateStudentChart, setDateStudentChart] = useState(new Date())
@ -39,6 +43,8 @@ export default function DetailRoomEducation() {
const [offsetOnline, setOffsetOnline] = useState(0); const [offsetOnline, setOffsetOnline] = useState(0);
const [isEndOnlineClasses, setIsEndOnlineClasses] = useState(false); const [isEndOnlineClasses, setIsEndOnlineClasses] = useState(false);
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [searchText, setSearchText] = useState('');
const dispatch = useDispatch();
const getListOrganization = async () => { const getListOrganization = async () => {
try { try {
@ -190,9 +196,15 @@ export default function DetailRoomEducation() {
} }
const goToDetailSchool = (item) => { const goToDetailSchool = (item) => {
history.push(replacePathParams(PATH.home.detailSchool, {schoolId: item?.organization_id}) + const schoolId = item?.organization_id;
"?school_name=" + const schoolName = encodeURIComponent(item?.organization_name);
encodeURIComponent(item?.organization_name)); const detailPath = replacePathParams(PATH.home.detailSchool, { schoolId});
history.push({
pathname: detailPath,
search: `?school_name=${schoolName}`,
state: { isBack: true }
});
} }
useEffect(() => { useEffect(() => {
@ -279,13 +291,64 @@ export default function DetailRoomEducation() {
setIsLoading(false); 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 ( return (
<div className="flex-1"> <div className="flex-1">
<Header <Header
icon={renderIconHome({ color: "#4D4D4D" })} icon={renderIconHome({ color: "#4D4D4D" })}
title={"Phòng giáo dục " + authentication.user.province} title={"Phòng giáo dục " + authentication.user.province}
manager={true} manager={true}
isBack={isBack}
/> />
<div className="container-page-header container-page-sidebar"> <div className="container-page-header container-page-sidebar">
<div className="detail-room-education-container bg-sub-main-green-img"> <div className="detail-room-education-container bg-sub-main-green-img">
@ -335,7 +398,35 @@ export default function DetailRoomEducation() {
</div> </div>
<div className="detail-room-education-right-side"> <div className="detail-room-education-right-side">
<div className="detail-room-education-list-container"> <div className="detail-room-education-list-container">
<div className="detail-room-education-header">
<span style={{fontSize: '2rem', fontWeight: 700, padding: '0 3.2rem'}}>Danh sách trường</span> <span style={{fontSize: '2rem', fontWeight: 700, padding: '0 3.2rem'}}>Danh sách trường</span>
<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={false}
onClick={handleSubmit}
>
{"Tìm kiếm"}
</PrimaryButton>
<PrimaryButton onClick={handleExport}>
Xuất excel
</PrimaryButton>
</div>
</div>
<div className="flex gap-16 align-item-center" style={{padding: '1rem 3.2rem'}}> <div className="flex gap-16 align-item-center" style={{padding: '1rem 3.2rem'}}>
<RootSelect <RootSelect
data={LIST_SCHOOL_YEAR} data={LIST_SCHOOL_YEAR}

@ -35,11 +35,34 @@
// height: 34px; // height: 34px;
// } // }
// } // }
.education-department-home-header{
width: 100%;
padding: 0 32px;
.detail-education-department-list-header{
justify-content: space-around;
margin: 1.2rem 0;
gap: 32px;
@media (max-width: 1650px) {
flex-direction: column;
}
.criteria-manage-search-input {
height: 46px;
border-radius: 40px;
@include screen_pc_sm {
height: 36px;
}
}
.criteria-manage-item {
min-width: fit-content;
flex: 1;
}
}
}
.education-department-home-note { .education-department-home-note {
font-size: 2rem; font-size: 2rem;
font-weight: 700; font-weight: 700;
padding-left: 3.2rem;
padding-bottom: 1.2rem; padding-bottom: 1.2rem;
} }
@ -49,6 +72,7 @@
flex-direction: column; flex-direction: column;
padding: 0 3.2rem; padding: 0 3.2rem;
max-height: 740px; max-height: 740px;
padding-top: 1.2rem;
.education-department-home-list-room { .education-department-home-list-room {
flex: 1; flex: 1;

@ -2,6 +2,7 @@ import { useEffect, useState } from "react";
import InputText from "../../../_components/Auth/InputText"; import InputText from "../../../_components/Auth/InputText";
import Header from "../../../_components/Header"; import Header from "../../../_components/Header";
import { import {
renderIconBook,
renderIconButton, renderIconButton,
renderIconHome, renderIconHome,
renderIconSearchInput, renderIconSearchInput,
@ -15,7 +16,8 @@ import PrimaryButton from "../../../_components/Button/PrimaryButton";
import { apiCaller, history } from "../../../_helpers"; import { apiCaller, history } from "../../../_helpers";
import { PATH } from "../../../_constants"; import { PATH } from "../../../_constants";
import { replacePathParams } from "../../../_helpers/utils"; import { replacePathParams } from "../../../_helpers/utils";
import { useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { alertActions } from "../../../_actions";
export default function EducationDepartmentHome() { export default function EducationDepartmentHome() {
const authentication = useSelector((state) => state.authentication); const authentication = useSelector((state) => state.authentication);
@ -31,6 +33,7 @@ export default function EducationDepartmentHome() {
const [offsetOnline, setOffsetOnline] = useState(0); const [offsetOnline, setOffsetOnline] = useState(0);
const [isEndOnlineClasses, setIsEndOnlineClasses] = useState(false); const [isEndOnlineClasses, setIsEndOnlineClasses] = useState(false);
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const dispatch = useDispatch();
const getDataOrganization = async () => { const getDataOrganization = async () => {
try { try {
@ -83,41 +86,57 @@ export default function EducationDepartmentHome() {
} }
const goToDetailRoomEducation = (item) => { const goToDetailRoomEducation = (item) => {
history.push(replacePathParams(PATH.home.detailRoomEducation, {idRoom: item?.id})) const idRoom = item?.id;
const detailPath = replacePathParams(PATH.home.detailRoomEducation, { idRoom });
history.push({
pathname: detailPath,
state: { isBack: true },
});
} }
useEffect(() => { useEffect(async () => {
getDataOrganization() await getDataOrganization()
getDataStatisticCircle() await getDataStatisticCircle()
}, []) }, [])
useEffect(() => { useEffect(async () => {
getDataStudentChart() await getDataStudentChart()
}, [dateStudentChart]) }, [dateStudentChart])
useEffect(() => { useEffect(async () => {
getDataTeacherChart() await getDataTeacherChart()
}, [dateTeacherChart]) }, [dateTeacherChart])
const renderIconBook = () => { const getDataTeacher = async () => {
return ( try {
<svg setIsLoading(true);
width="29" const endPoint = `/api_teacher/get_teacher_info?search=${searchText}`;
height="29" const res = await apiCaller(endPoint, "GET");
viewBox="0 0 29 29" setIsLoading(false);
fill="none" if (res?.status) {
xmlns="http://www.w3.org/2000/svg" const teacherId = res?.data?.[0]?.teacher_id;
> const teacherName = encodeURIComponent(res?.data?.[0]?.teacher_name);
<path const detailPath = replacePathParams(PATH.home.detailTeacher, { teacherId});
d="M15.2359 2.71875L3.12973 6.05873H3.11342C2.91223 6.05873 0.90625 6.11492 0.90625 8.35789C0.90625 9.33256 1.33853 10.0589 1.33853 10.0589L10.5614 25.4842C11.4432 26.8889 13.316 26.0094 13.316 26.0094L27.4585 19.1196L26.9292 18.5827C26.8046 17.9379 26.7321 16.7439 27.6075 15.8548C27.627 15.8349 27.6307 15.8077 27.6411 15.7828L28.0938 15.6011L15.2359 2.71875ZM15.6115 5.66044L18.0869 8.35517L8.84727 11.7387L6.66502 8.30578L15.6115 5.66044ZM10.2343 23.1719L2.12153 9.60172C2.11791 9.59673 1.8125 9.05389 1.8125 8.35789C1.8125 7.4752 2.24478 7.13944 2.66755 7.02208L11.9444 21.4931C11.2461 21.7953 10.4658 22.4859 10.2343 23.1719ZM26.4679 17.2826C26.4385 17.4911 26.4235 17.6941 26.4267 17.8844L17.1426 22.291L26.4598 18.3371C26.4688 18.4096 26.477 18.4816 26.4883 18.5469L14.587 24.2952L26.5821 18.9751L26.5894 19.0036L13.316 25.3533C13.3096 25.3573 12.7038 25.6795 12.0966 25.6795C11.4967 25.6795 11.1229 25.3714 10.9525 24.7379C10.5143 23.1103 13.0038 22.1877 13.0414 22.1741L26.8087 16.2178C26.7099 16.399 26.6415 16.5839 26.5844 16.7674L17.845 20.8814L26.4679 17.2826Z"
fill="white" history.push({
/> pathname: detailPath,
</svg> search: `?teacher_name=${teacherName}`,
state: { isBack: true }
});
}
} catch (err) {
setIsLoading(false);
dispatch(
alertActions.error({
message: err?.toString(),
}),
); );
}
}; };
const handleSubmit = ()=>{ const handleSubmit = () =>{
getDataTeacher()
} }
const handleScroll = (e) => { const handleScroll = (e) => {
@ -175,7 +194,7 @@ export default function EducationDepartmentHome() {
<div className="container-page-header container-page-sidebar"> <div className="container-page-header container-page-sidebar">
<div className="education-department-home-container bg-sub-main-green-img"> <div className="education-department-home-container bg-sub-main-green-img">
<div className="education-department-statistic-container"> <div className="education-department-statistic-container">
{!!data ? <div className="d-flex gap-16" style={{height: '80%'}}> {!!data ? <div className="d-flex gap-16" style={{height: '90%'}}>
<div className="education-department-statistic-col gap-16"> <div className="education-department-statistic-col gap-16">
<BoxDoughnutChart data={[data?.district_join, data?.total_district]} title={'Số huyện đã tham gia'} /> <BoxDoughnutChart data={[data?.district_join, data?.total_district]} title={'Số huyện đã tham gia'} />
<BoxDoughnutChart data={[data?.school_join, data?.total_school]} title={'Số trường đã tham gia'} /> <BoxDoughnutChart data={[data?.school_join, data?.total_school]} title={'Số trường đã tham gia'} />
@ -219,23 +238,33 @@ export default function EducationDepartmentHome() {
</div> </div>
</div> </div>
<div className="education-department-home-list-container"> <div className="education-department-home-list-container">
<div className="education-department-home-header">
<p className="education-department-home-note"> <p className="education-department-home-note">
Danh sách phòng giáo dục Danh sách phòng giáo dục
</p> </p>
{/* <InputText <div className="d-flex detail-education-department-list-header">
className="search-input" <InputText
className="criteria-manage-search-input criteria-manage-item"
value={searchText} value={searchText}
setValue={setSearchText} setValue={setSearchText}
type="text" type="text"
name="searchText" name="searchText"
placeholder={"Nhập tên giáo viên"} placeholder={"Nhập email hoặc số điện thoại giáo viên"}
renderLabelIcon={renderIconSearchInput} renderLabelIcon={renderIconSearchInput}
onKeyUp={(e) => { onKeyUp={(e) => {
if (e.which == 13 && !isFilterSchool) { if (e.which == 13 && !isFilterSchool) {
handleSubmit(); handleSubmit();
} }
}} }}
/> */} />
<PrimaryButton
isDisabled={false}
onClick={handleSubmit}
>
{"Tìm kiếm"}
</PrimaryButton>
</div>
</div>
<div onScroll={handleScroll} className="education-department-home-list-content scrollbar-custom"> <div onScroll={handleScroll} className="education-department-home-list-content scrollbar-custom">
<div className="education-department-home-list-room"> <div className="education-department-home-list-room">
{listOrganization.length > 0 ? listOrganization.map((item, index) => ( {listOrganization.length > 0 ? listOrganization.map((item, index) => (

@ -13,7 +13,7 @@ import {
TYPE_DISPATCH, TYPE_DISPATCH,
} from "../../../_constants/common"; } from "../../../_constants/common";
import { apiCaller, history } from "../../../_helpers"; import { apiCaller, history } from "../../../_helpers";
import { useParams } from "react-router-dom"; import { useLocation, useParams } from "react-router-dom";
import { exportExcel, replacePathParams } from "../../../_helpers/utils"; import { exportExcel, replacePathParams } from "../../../_helpers/utils";
import { configConstants, PATH } from "../../../_constants"; import { configConstants, PATH } from "../../../_constants";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
@ -28,7 +28,8 @@ export default function HeadmasterHome() {
const params = new URLSearchParams(search); const params = new URLSearchParams(search);
const school_name = params.get("school_name"); const school_name = params.get("school_name");
const {schoolId} = useParams(); const {schoolId} = useParams();
const location = useLocation();
const isBack = location.state?.isBack;
const authentication = useSelector((state) => state.authentication); const authentication = useSelector((state) => state.authentication);
const grade = useSelector((state) => state.grade); const grade = useSelector((state) => state.grade);
const dispatch = useDispatch() const dispatch = useDispatch()
@ -115,13 +116,15 @@ export default function HeadmasterHome() {
}; };
const handleClickTeacherItem = (item) => { const handleClickTeacherItem = (item) => {
history.push( const teacherId = item?.teacher_id;
replacePathParams(PATH.home.detailTeacher, { const teacherName = encodeURIComponent(item?.teacher_name);
teacherId: item?.teacher_id, const detailPath = replacePathParams(PATH.home.detailTeacher, { teacherId });
}) +
"?teacher_name=" + history.push({
encodeURIComponent(item?.teacher_name), pathname: detailPath,
); search: `?teacher_name=${teacherName}`,
state: { isBack: true },
});
} }
const handleClickGradeItem = (item) => { const handleClickGradeItem = (item) => {
@ -254,7 +257,7 @@ export default function HeadmasterHome() {
<Header <Header
icon={renderIconHome({ color: "#4D4D4D" })} icon={renderIconHome({ color: "#4D4D4D" })}
title={schoolName} title={schoolName}
isBack={true} isBack={isBack}
/> />
<div className="container-page-header container-page-sidebar"> <div className="container-page-header container-page-sidebar">
<div className="headmaster-home-container bg-main-img"> <div className="headmaster-home-container bg-main-img">

@ -3,13 +3,14 @@ import Header from "../../../_components/Header";
import { renderIconHome } from "../../../_components/renderIcon"; import { renderIconHome } from "../../../_components/renderIcon";
import RateStar from "../../../_components/RateStar"; import RateStar from "../../../_components/RateStar";
import { defaultMonthYearSemester, getListMonthBySemester, LIST_SCHOOL_YEAR, LIST_SEMESTER } from "../../../_constants/common"; import { defaultMonthYearSemester, getListMonthBySemester, LIST_SCHOOL_YEAR, LIST_SEMESTER } from "../../../_constants/common";
import { configConstants } from "../../../_constants"; import { configConstants, PATH } from "../../../_constants";
import RootSelect from "../../../_components/RootSelect"; import RootSelect from "../../../_components/RootSelect";
import PrimaryButton from "../../../_components/Button/PrimaryButton"; import PrimaryButton from "../../../_components/Button/PrimaryButton";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import './outstandingTeacher.style.scss' import './outstandingTeacher.style.scss'
import { apiCaller } from "../../../_helpers"; import { apiCaller, history } from "../../../_helpers";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { replacePathParams } from "../../../_helpers/utils";
export default function OutstandingTeacher() { export default function OutstandingTeacher() {
@ -55,11 +56,24 @@ export default function OutstandingTeacher() {
getData() getData()
}, []) }, [])
const handleClickTeacherItem = (item) => {
const teacherId = item?.teacher_id;
const teacherName = encodeURIComponent(item?.teacher_name);
const detailPath = replacePathParams(PATH.home.detailTeacher, { teacherId });
history.push({
pathname: detailPath,
search: `?teacher_name=${teacherName}`,
state: { isBack: true },
});
}
return ( return (
<div className="flex-1"> <div className="flex-1">
<Header <Header
icon={renderIconHome({ color: "#4D4D4D" })} icon={renderIconHome({ color: "#4D4D4D" })}
title={"Top 10 giáo viên tiêu biểu - " + authentication.user.province} title={"Top 10 giáo viên tiêu biểu - " + authentication.user.province}
isBack={true}
/> />
<div className="container-page-header container-page-sidebar"> <div className="container-page-header container-page-sidebar">
<div className="outstanding-teacher-container bg-outstanding-img"> <div className="outstanding-teacher-container bg-outstanding-img">
@ -87,8 +101,8 @@ export default function OutstandingTeacher() {
Áp dụng Áp dụng
</PrimaryButton> </PrimaryButton>
</div> </div>
{!!firstTeacher && <div className="outstanding-teacher-best-container"> {!!firstTeacher && <div className="outstanding-teacher-best-container" >
<div className="outstanding-teacher-best-avatar-content"> <div className="outstanding-teacher-best-avatar-content" onClick={() => handleClickTeacherItem(firstTeacher)}>
<div className="outstanding-teacher-best-avatar-box"> <div className="outstanding-teacher-best-avatar-box">
<img className="outstanding-teacher-best-crown" src="/assets/imgs/crown_warning.png" /> <img className="outstanding-teacher-best-crown" src="/assets/imgs/crown_warning.png" />
<img className="outstanding-teacher-best-avatar" src={configConstants.BASE_URL + firstTeacher?.avatar} /> <img className="outstanding-teacher-best-avatar" src={configConstants.BASE_URL + firstTeacher?.avatar} />

@ -40,6 +40,7 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
max-height: 290px; max-height: 290px;
cursor: pointer;
.outstanding-teacher-best-avatar-box { .outstanding-teacher-best-avatar-box {
height: 90%; height: 90%;

@ -19,13 +19,15 @@ import { useEffect, useState,useRef } from "react";
import { apiCaller, history } from "../../../_helpers"; import { apiCaller, history } from "../../../_helpers";
import { configConstants } from "../../../_constants"; import { configConstants } from "../../../_constants";
import { exportExcel } from "../../../_helpers/utils"; import { exportExcel } from "../../../_helpers/utils";
import { useParams } from "react-router-dom"; import { useLocation, useParams } from "react-router-dom";
export default function TeacherHome() { export default function TeacherHome() {
const search = history?.location?.search; const search = history?.location?.search;
const params = new URLSearchParams(search); const params = new URLSearchParams(search);
const teacher_name = params.get("teacher_name"); const teacher_name = params.get("teacher_name");
const { teacherId } = useParams(); const { teacherId } = useParams();
const location = useLocation();
const isBack = location.state?.isBack;
const authentication = useSelector((state) => state.authentication); const authentication = useSelector((state) => state.authentication);
const [schoolYear, setSchoolYear] = useState( const [schoolYear, setSchoolYear] = useState(
defaultMonthYearSemester.schoolYear, defaultMonthYearSemester.schoolYear,
@ -226,6 +228,7 @@ export default function TeacherHome() {
<Header <Header
icon={renderIconHome({ color: "#4D4D4D" })} icon={renderIconHome({ color: "#4D4D4D" })}
title={"Danh sách lớp của giáo viên " + teacherName} title={"Danh sách lớp của giáo viên " + teacherName}
isBack={isBack}
/> />
<div className="container-page-header container-page-sidebar"> <div className="container-page-header container-page-sidebar">
<div className="teacher-home-container bg-main-img"> <div className="teacher-home-container bg-main-img">

Loading…
Cancel
Save